views:

2550

answers:

10

I maintain an application that has a .aspx page that loads on image from the database and uses Response.BinaryWrite() to write it back to the client. This worked perfectly not long ago. Two things have changed, we upgraded the application to .NET 3.5 and they upgraded all the computers at work to IE7.

Everything works fine on Firefox, but all I get in IE7 is a red X. So I assume this issue is related to IE7? Is there a security setting somewhere that would stop it from loading images from a .aspx form? It's already set to display based on the content type and not the extension.

Here is some of the code. Like I said, I just maintain this app and didn't write it. I know using Session is not a great way of doing it, but it's what I have and the switch statement is just a "wtf?".

<asp:image id="imgContent" runat="server" Visible="true" ImageUrl="ProductContentFormImage.aspx"></asp:image>

 protected void Page_Load(object sender, System.EventArgs e)
 {
  Hashtable hshContentBinary = (Hashtable)Session["hshContentBinary"];
  byte[] content = (byte[]) hshContentBinary["content"];
  string extension = (string) hshContentBinary["extension"];


  string contentTypePrefix = "application";
  switch(extension.ToLower())
  {
   case "gif":
   case "jpg":
   case "bmp":
    contentTypePrefix = "image";
    break;
   case "tif":
    contentTypePrefix = "image";
    break;
   case "tiff":
    contentTypePrefix = "image";
    break;
   case "eps":
    contentTypePrefix = "image";
    break;
   default:
    Response.AppendHeader( 
     "Content-disposition",
     "attachment; filename=content." + extension );
    break;
  }
  Response.ContentType = contentTypePrefix + "/" + extension;
  Response.BinaryWrite(content);
 }

EDIT:

OK, I followed your suggestions and through a little more research I have changed the method to the following, but it still doesn't work.

protected void Page_Load(object sender, System.EventArgs e)
{
    Hashtable hshContentBinary = (Hashtable)Session["hshContentBinary"];
    byte[] content = (byte[]) hshContentBinary["content"];
    string extension = (string) hshContentBinary["extension"];
    string contentType;
    string contentDisposition = "inline; filename=content." + extension;

    Response.ClearContent();
    Response.ClearHeaders();
    Response.Clear();

    switch(extension.ToLower())
    {
     case "gif":
      contentType = "image/gif";
      break;
     case "jpg":
     case "jpe":
     case "jpeg":
      contentType = "image/jpeg";
      break;
     case "bmp":
      contentType = "image/bmp";
      break;
     case "tif":
     case "tiff":
      contentType = "image/tiff";
      break;
     case "eps":
      contentType = "application/postscript";
      break;
     default:
      contentDisposition = "attachment; filename=content." + extension;
      contentType = "application/" + extension.ToLower();
      break;
    }

    Response.Buffer = true;
    Response.Expires = 0;
    Response.ContentType = contentType;
    Response.AddHeader("Content-Length", content.Length.ToString());
    Response.AddHeader("Content-disposition", contentDisposition);
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.BinaryWrite(content);
    Response.End();
}
A: 

You might try a...

Response.ClearContent();
Response.ClearHeaders();

...right before...

Response.ContentType = contentTypePrefix + "/" + extension;

We had to do that to get the correct file type association in IE7.

Eddie
A: 

Try setting your content-disposition to inline instead of attachment, like:

Response.AppendHeader( 
   "Content-disposition",
   "inline; filename=content." + extension );

While most browsers are very flexible in this respect, "attachment" was intended to require further action by the user. IETF RFC 1806:

The display of an attachment is generally construed to require positive action on the part of the recipient, while inline message components are displayed automatically when the message is viewed.

Chris Pebble
+1  A: 

Your mime types are not correct. This works better, at least for the images:

string contentType = "application/" + extension.ToLower();
switch(extension.ToLower()) {
   case "gif": contentType = "image/gif"; break;
   case "jpg":
   case "jpeg":
   case "jpe": contentType = "image/jpeg"; break;
   case "bmp": contentType = "image/bmp"; break;
   case "tif":
   case "tiff": contentType = "image/tiff"; break;
   case "eps": contentType = "application/postscript"; break;
   default:
      Response.AppendHeader( 
         "Content-disposition",
         "attachment; filename=content." + extension );
      break;
}
Response.ContentType = contentType;

Hera are mime types and file extensions, if you need to add more: http://www.w3schools.com/media/media_mimeref.asp

Guffa
A: 

Get yourself a copy of Fiddler so you can see what the response to the image URL is.

If possible change the ASPX to a ASHX instead.

AnthonyWJones
A: 

I can tell you that this way of image loading works fine in IE7 (just had written same sorta code some time back). So, there could be following issues: 1) Try doing a Response.Clear() before setting the ContentyType and do a response.end in the end. 2) Make sure that your extension in the session is without the period (.) i.e. it should be just gif for .gifs, jpg for .jpg etc.

S

Sachin
A: 

Try going to another website in IE7.
Does it show the images for any other website?

If it doesn't show images, I am guessing that you might have some setting (e.g. web developer toolbar OR fiddler) to "not to load images".

shahkalpesh
A: 

Your code is very complicated, why not simplify it a bit, so that you're only setting the content type?

Here's code i use, and it works in all browsers.

protected void Page_Load(object sender, EventArgs e)
{
  byte[] jpg = .....

  Response.Clear();
  Response.ContentType = "image/jpeg";
  Response.BinaryWrite(jpg);
  Response.End();
}
Chris
+1  A: 

Consider setting up your page with some caching including client side cache control headers. When you do this make sure that you set a different filename for each individual image

contentDisposition = String.Format("attachment; filename=content{0).{1}",fileName, fileExtension);

and the client side cache headers

context.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(YourDatabaseImageOrConfigFile.CacheSeconds));
context.Response.Cache.SetOmitVaryStar(true);
context.Response.Cache.SetLastModified(YourDatabaseImage.ModifiedDate);

I would make this page into an ASHX http handler as well to get rid of the overhead of the page lifecycle.

I have this whole thing written a few times over and can provide the code if needed. This image endpoint is on a site doing around 80 requests a second.

Ira Miller
A: 

The image was corrupted in a way that IE7 could not display it, but Firefox could. The image was large it wouldn't fit on the screen and I didn't see where it was cut off.

Thanks for all your suggestions.

jhunter
A: 

I am not 100 percent sure about IE7, however I ran into a similar issue with ie8. The solution to my issue was to make sure that I covered the content type for "image/pjpeg". Not sure how many different coverages you need, but this one solved my issue.

Jeff Ancel