3

I implemented a generic handler in my application which works great for images, but when I manually type the handler URL in the browser with the image's querystring it prompts download instead of displaying. Here is my code:

public void ProcessRequest(HttpContext context)
        {
            if (this.FileName != null)
            {
                string path = Path.Combine(ConfigurationManager.UploadsDirectory, this.FileName);

                if (File.Exists(path) == true)
                {
                    FileStream file = new FileStream(path, FileMode.Open);
                    byte[] buffer = new byte[(int)file.Length];
                    file.Read(buffer, 0, (int)file.Length);
                    file.Close();
                    context.Response.ContentType = "application/octet-stream";
                    context.Response.AddHeader("content-disposition", "attachment; filename=\"" + this.FileName + "\"");
                    context.Response.BinaryWrite(buffer);
                    context.Response.End();
                }
            }
        }

I am using the octet-stream because I'm dealing with more than just images and I don't always know the content type of the file. Thanks in advance!

Mike Cole
  • 14,474
  • 28
  • 114
  • 194

3 Answers3

6

The only way is to specify correct ContentType so the browser know what to do with receiving file, depending on installed plugins (for example, view pdf files in browser frame) and system assosiations (for example, offer to open document in MS Office instead of simple download)

You can try to specify Content Type depending on file extension, i.e.:

if(Path.GetExtension(path) == ".jpg")
   context.Response.ContentType = "image/jpeg";
else
   context.Response.ContentType = "application/octet-stream";
Pavel Morshenyuk
  • 10,891
  • 4
  • 32
  • 38
  • 3
    I'd hard-code a few obvious cases, e.g. jpg -> image/jpeg, then you can look up the rest from the registry e.g. the code in this question http://stackoverflow.com/questions/3442607/mime-types-in-the-windows-registry . (although I'd maintain a local cache in the app because I'm nervous hitting the registry from .NET would be an expensive operation) – Rup Aug 10 '10 at 18:34
  • @Rup great idea about using registry! – Pavel Morshenyuk Aug 10 '10 at 18:42
  • 1
    That's what IIS does. Although as in the question I've linked servers are often missing registry entries for e.g. .pdf or .flv (that's the one that's burned me in the past). – Rup Aug 10 '10 at 18:44
1

If you store the ContentType as part of the files metadata, when you pull it back down your could use it.

theFile = GetFile(id)
context.Response.ContentType = theFile.Type;
Ivan
  • 10,052
  • 12
  • 47
  • 78
Spencer
  • 11
  • 1
-1

The content-disposition header is the one that causes your browser to show the download dialog. Remove that line and it will show in the browser.

ZippyV
  • 12,540
  • 3
  • 37
  • 52