This post applies to Sitecore 5.3.1:
Two weeks ago I had to create a simple page which allowed users to download any file from the Media Library. And as the customer might provide images, pdfs, etc, and you don’t know which viewer the visitor uses, you want to force them to download the file. I’ve created a pipeline processor who handles this for you, just by adding dl=true to your url. But wait hey… you can define this in your web.config?! Yeah that’s true, but this would mean you have to download every type of file, I’m sure our customer doesn’t want that. So here’s my processor:
1 public class DownloadProcessor
2 {
3 public void Process(GetMediaStreamPipelineArgs args)
4 {
5 if(GetBoolFromQueryString(“dl”, false))
6 {
7 WriteCacheHeaders(args);
8 }
9 }
10
11 #region Private static method(-s)
12 private static void WriteCacheHeaders(GetMediaStreamPipelineArgs args)
13 {
14 //Clear all headers to make sure any others are sent to the client
15 args.OutputStream.Headers.Headers.Clear();
16
17 //Sent the force download type to your client
18 args.OutputStream.Headers.Add(“Content-Type”, “application/force-download”);
19
20 //Pass the right username
21 args.OutputStream.Headers.Add(“Content-Disposition”, “attachment; filename=” + GetFileName(args.MediaData.MediaItem));
22
23 //Add the length of the file in bytes
24 args.OutputStream.Headers.Add(“Content-Length”, args.MediaData.MediaItem.Size.ToString());
25
26 //Make the client aware of the binary stream
27 args.OutputStream.Headers.Add(“Content-Transfer-Encoding”, “binary”);
28 }
29
30 private static string GetFileName(MediaItem mi)
31 {
32 //Get the item name
33 string workName = mi.Name;
34
35 //When the file ends with its own extention, try to cut this part of
36 if(workName.EndsWith(mi.Extension, StringComparison.CurrentCultureIgnoreCase))
37 {
38 workName = workName.Substring(0, workName.Length – mi.Extension.Length).Trim();
39 }
40
41 //Replace the spaces with undersquares so browser compatibility is ensured
42 workName = workName.Replace(‘ ‘, ‘_’);
43
44 //Add the extension to the file
45 workName = string.Concat(workName, “.”, mi.Extension);
46
47 return workName;
48 }
49
50 private static bool GetBoolFromQueryString(string qsName, bool defaultValue)
51 {
52 string qsValue = global::Sitecore.Context.Request.QueryString.Get(qsName);
53 if(!string.IsNullOrEmpty(qsValue))
54 {
55 bool parsedValue;
56 if(bool.TryParse(qsValue, out parsedValue))
57 {
58 return parsedValue;
59 }
60 }
61 return defaultValue;
62 }
63 #endregion
64 }
Configuring can be done in the getMediaStream-pipeline.
Note: Haven’t tested this solution with files larger then 2 Mb. Make sure to do some representive load testing when you are going to use this solution for larger files.

Hello Alex,
First, thank you for your insight into SiteCore. I am a relatively new developer and am learning a great deal about the software from websites such as yours.
My question – How would I go about implementing this code you list above? I am not familiar with pipelines inside of SiteCore. I have run google searches that have taught me a little bit of information, but if you could provide some additional insight as to how your code above is actually used, I would be very happy!
Thank You,
Devin
Chicago, IL USA
Hi Alex,
Just following the Devin I aslo would like to say, it woould be very much appreciated if you write a sample code how to use it. Cos, in my code I can not get the “getMediaStreamArg” anywhere. What I found frkom a media item is only MediaStrem which is type of media stream.
So, please write something on that to help us upt, it is urgent to me.
Thanks in advance
Hello Alex,
Is it possible to disable download for video files, in particular *.wmv ?
setting forcedownload = false in web.config did not help for video files. would like to stream a video and avoid the download dialog box.
Thank You.