I'm currently using a HttpResponse to download files from my Server. I already have a couple functions being used to download Excel/Word files, but I'm having trouble getting my simple Text file (.txt) to download.
With the text file I'm basically dumping contents of a TextBox into a File, attempting to download the file with the HttpResponse and then delete the Temporary Text File.
Here is an example of my code that works for the Excel/Word documents:
protected void linkInstructions_Click(object sender, EventArgs e)
{
String FileName = "BulkAdd_Instructions.doc";
String FilePath = Server.MapPath("~/TempFiles/BulkAdd_Instructions.doc");
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "application/x-unknown";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath);
response.Flush();
response.End();
}
And here is the chunk of code that doesn't work.
Taking Note that the code runs without throwing any errors. The File is created, and Deleted, but never dumped to the User.
protected void saveLog(object sender, EventArgs e)
{
string date = DateTime.Now.ToString("MM_dd_yyyy_hhmm"); // Get Date/Time
string fileName = "BulkLog_"+ date + ".txt"; // Stitch File Name + Date/Time
string logText = errorLog.Text; // Get Text from TextBox
string halfPath = "~/TempFiles/" + fileName; // Add File Name to Path
string mappedPath = Server.MapPath(halfPath); // Create Full Path
File.WriteAllText(mappedPath, logText); // Write All Text to File
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
response.TransmitFile(mappedPath); // Transmit File
response.Flush();
System.IO.File.Delete(mappedPath); // Delete Temporary Log
response.End();
}
It is because you are deleting the file before it can send.
From MSDN - HttpResponse.End Method
Sends all currently buffered output to
the client, stops execution of the
page, and raises the EndRequest event.
Try putting your System.IO.File.Delete(mappedPath); line after the response.End(); in my test just then it seemed to be working.
Also, might be a good idea to check if the file exists first, cant see any file.Exists in there, don't want any null reference exceptions, and to set the Content-Length.
EDIT: here is the code I used in a project at work a while ago, might help you out a bit.
// Get the physical Path of the file
string filepath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + folder + filename;
// Create New instance of FileInfo class to get the properties of the file being downloaded
FileInfo file = new FileInfo(filepath);
// Checking if file exists
if (file.Exists)
{
// Clear the content of the response
Response.ClearContent();
// LINE1: Add the file name and attachment, which will force the open/cance/save dialog to show, to the header
Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", file.Name));
// Add the file size into the response header
Response.AddHeader("Content-Length", file.Length.ToString());
// Set the ContentType
Response.ContentType = ReturnFiletype(file.Extension.ToLower());
// Write the file into the response (TransmitFile is for ASP.NET 2.0. In ASP.NET 1.1 you have to use WriteFile instead)
Response.TransmitFile(file.FullName);
// End the response
Response.End();
//send statistics to the class
}
And here is the Filetype method I used
//return the filetype to tell the browser.
//defaults to "application/octet-stream" if it cant find a match, as this works for all file types.
public static string ReturnFiletype(string fileExtension)
{
switch (fileExtension)
{
case ".htm":
case ".html":
case ".log":
return "text/HTML";
case ".txt":
return "text/plain";
case ".doc":
return "application/ms-word";
case ".tiff":
case ".tif":
return "image/tiff";
case ".asf":
return "video/x-ms-asf";
case ".avi":
return "video/avi";
case ".zip":
return "application/zip";
case ".xls":
case ".csv":
return "application/vnd.ms-excel";
case ".gif":
return "image/gif";
case ".jpg":
case "jpeg":
return "image/jpeg";
case ".bmp":
return "image/bmp";
case ".wav":
return "audio/wav";
case ".mp3":
return "audio/mpeg3";
case ".mpg":
case "mpeg":
return "video/mpeg";
case ".rtf":
return "application/rtf";
case ".asp":
return "text/asp";
case ".pdf":
return "application/pdf";
case ".fdf":
return "application/vnd.fdf";
case ".ppt":
return "application/mspowerpoint";
case ".dwg":
return "image/vnd.dwg";
case ".msg":
return "application/msoutlook";
case ".xml":
case ".sdxl":
return "application/xml";
case ".xdp":
return "application/vnd.adobe.xdp+xml";
default:
return "application/octet-stream";
}
}
I stumbled across this post in my search, and noticed that it wasn't useful in telling us why the UpdatePanel caused the issue in the first place.
The UpdatePanel is an asynchronous postback, and Response.TransmitFile needs a full postback to work properly.
The control that triggers the asynchronous postback needs to be made a trigger in the UpdatePanel:
<Triggers>
<asp:PostBackTrigger ControlID="ID_of_your_control_that_causes_postback" />
</Triggers>
Thank you for the follow up on what your problem was. I've spent hours trying to figure out why no error code was being thrown despite the fact that nothing happened. Turns out it was my AJAX UpdatePanel mysteriously and covertly getting in the way.
I resolved this issue. The Response object requires a full postback in order for it to download an Excel file generated on the server.. but the full postback was being prevented by the UpdatePanel on my webform, which contained my export button. So.. inside the UpdatePanel tag, I changed this...
<asp:AsyncPostBackTrigger ControlID="btnExport" EventName="Click" />
...to this to resolve the issue:
<asp:PostBackTrigger ControlID="btnExport"/>
Also try this for saving text on client side (Chrome only now) without the round trip to Server.
Here is another flash base one...
I ended up fixing the issue on my own. It turns out it was an Ajax Problem not allowing my Button to Postback properly. This stopped the TransmitFile from being fired.
Thanks for the help!
Related
I have a popup window that displays "Please wait while your file is being downloaded". This popup also executes the code below to start the file download. How can I close the popup window once the file download has completed? I need some way to detect that the file download has completed so I can call self.close() to close this popup.
System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ClearHeaders();
System.Web.HttpContext.Current.Response.ContentType = fileObject.ContentType;
System.Web.HttpContext.Current.Response.AppendHeader("Content-Disposition", string.Concat("attachment; filename=", fileObject.FileName));
System.Web.HttpContext.Current.Response.WriteFile(fileObject.FilePath);
Response.Flush();
Response.End();
An idea:
If you handle the file downloading yourself in server side code by writing chunk by chunk to the response stream, then you'll know when the file had finished downloading. You would simply have to connect the FileStream to the response stream, send data chunk by chunk, and redirecting after complete. This can be inside your popup window.
Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-disposition", "attachment; filename=bob.mp3");
Response.AppendHeader("content-length", "123456789");
Make sure you check Response.IsClientConnected when writing out to the response stream.
There is a solution where you can track the download status by transferring the file as smaller packets and check whether all the packets have been transferred.
The solution is not mine but you can find it here:
File Download in ASP.NET and Tracking the Status of Success/Failure of Download
//Function for File Download in ASP.Net in C# and
//Tracking the status of success/failure of Download.
private bool DownloadableProduct_Tracking()
{
//File Path and File Name
string filePath = Server.MapPath("~/ApplicationData/DownloadableProducts");
string _DownloadableProductFileName = "DownloadableProduct_FileName.pdf";
System.IO.FileInfo FileName = new System.IO.FileInfo(filePath + "\\" + _DownloadableProductFileName);
FileStream myFile = new FileStream(filePath + "\\" + _DownloadableProductFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//Reads file as binary values
BinaryReader _BinaryReader = new BinaryReader(myFile);
//Ckeck whether user is eligible to download the file
if (IsEligibleUser())
{
//Check whether file exists in specified location
if (FileName.Exists)
{
try
{
long startBytes = 0;
string lastUpdateTiemStamp = File.GetLastWriteTimeUtc(filePath).ToString("r");
string _EncodedData = HttpUtility.UrlEncode(_DownloadableProductFileName, Encoding.UTF8) + lastUpdateTiemStamp;
Response.Clear();
Response.Buffer = false;
Response.AddHeader("Accept-Ranges", "bytes");
Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
Response.AppendHeader("Last-Modified", lastUpdateTiemStamp);
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName.Name);
Response.AddHeader("Content-Length", (FileName.Length - startBytes).ToString());
Response.AddHeader("Connection", "Keep-Alive");
Response.ContentEncoding = Encoding.UTF8;
//Send data
_BinaryReader.BaseStream.Seek(startBytes, SeekOrigin.Begin);
//Dividing the data in 1024 bytes package
int maxCount = (int)Math.Ceiling((FileName.Length - startBytes + 0.0) / 1024);
//Download in block of 1024 bytes
int i;
for (i = 0; i < maxCount && Response.IsClientConnected; i++)
{
Response.BinaryWrite(_BinaryReader.ReadBytes(1024));
Response.Flush();
}
//if blocks transfered not equals total number of blocks
if (i < maxCount)
return false;
return true;
}
catch
{
return false;
}
finally
{
Response.End();
_BinaryReader.Close();
myFile.Close();
}
}
else System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(),
"FileNotFoundWarning","alert('File is not available now!')", true);
}
else
{
System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(),
"NotEligibleWarning", "alert('Sorry! File is not available for you')", true);
}
return false;
}
Even though this is an old question it hasn't been answered all this time and I believe it deserves a (better) answer:
https://stackoverflow.com/a/59010319/313935
Some hacks are around that involves knowing when the last piece of the buffer has been sent or checking the HttpResponse.IsClientConnected property.
The way to do that is in your pop-up to call the server via AJAX polling for some response which would indicate the file was flushed.
Ex: right before sending the file, store sessionID+FileName in a DB or session or what have you.
On the client, in your popup, poll a web-service via AJAX - this could even be a WebMethod like Bool IsContentFlushed(string sessionID, string fileName);
After you do Response.Flush(); remove this sessionID+FileName from your store.
Call Response.Close() instead of Response.End() - the later is very brutal, and is usually over-kill.
I handle the problem differently in Javascript, which might or might not work for you.
Create a hidden DIV element, with the
message 'File is downloading...'
rather than a pop-up box.
Show the div when the download
starts
Once any other element on the
forms is clicked, hide the div
again..
You could also set a timer to hide
the download message div after so
amount of time...
I figure once the user clicks on another element, she either already knows the download is done, or she is ready to do something else, so the message becomes irrelevant and can go away....
I have written the below lines of code in c#
private void DownloadFile(byte[] myData, string Name)
{
Response.Expires = 0;
Response.Clear();
string ext= System.IO.Path.GetExtension(Name);
switch(ext)
{
case ".mp3":
Response.ContentType = "audio/mpeg";
break;
default:
Response.ContentType = "Application/octet-stream";
break;
}
Response.AddHeader("content-length", myData.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + Name);
try
{
Response.BinaryWrite(myData);
}
catch { }
Response.Flush();
Response.End();
}
Now the issue is that whenever we click mp3 file to download, it's directly played. I want that it should download it. Also I want that all types of files should be downloaded.
I struggled with this for the longest time, but finally solved the puzzle. Use Response.WriteFile. You could follow it with Response.Flush but I found that to be unnecessary. Extra headers were not necessary with .mp3 files. In my case, the .mp3 files were in a folder directly under the root. And here's a bonus: The key ingredients for making the .mp3 download work with smartphones (which was my dilemma) were using Response.End, and telling the mobile device that the download was done by sending back the Response.StatusCode = 200.
string FilenameMP3 = "~/someFolder/xyz.mp3";
string headerFilename = Filename.Substring(Filename.IndexOf("/") + 1);
Response.AppendHeader("Content-Disposition", String.Concat("attachment;filename=\"", headerFilename, "\""));
Response.ContentType = "audio/mpeg";
try
{
Response.WriteFile(Filename, true);
Response.End();
}
finally
{
Response.StatusCode = 200;
Response.Close();
}
What you have should be sufficient, assuming that the headers you added aren't being stripped / corrupted in transit (simple to check via Fiddler or similar).
Since you don't want the browser to interpret this data, a pragmatic option might be to simply send all data as "application/octet-stream", regardless of the content. While the "attachment" disposition should be sufficient for this, this approach is explicitly called out in RFC 2616, 19.5.1 ("Content-Disposition"):
If this header is used in a response with the application/octet- stream content-type, the implied suggestion is that the user agent should not display the response, but directly enter a `save response as...' dialog.
I am trying to download some text output from the screen as a text file. Following is the code. It's working on some pages and not working at all on other pages. Can anyone please suggest what's wrong here?
protected void Button18_Click(object sender, EventArgs e){
Response.Clear();
Response.Buffer = true;
Response.ContentType = "text/plain";
Response.AppendHeader("content-disposition", "attachment;filename=output.txt");
StringBuilder sb = new StringBuilder();
string output = "Output";
sb.Append(output);
sb.Append("\r\n");
Response.Write(sb.ToString());
}
As already mentioned by Joshua, you need to write the text to the output stream (Response). Also, don’t forget to invoke Response.End() after that.
protected void Button18_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
string output = "Output";
sb.Append(output);
sb.Append("\r\n");
string text = sb.ToString();
Response.Clear();
Response.ClearHeaders();
Response.AppendHeader("Content-Length", text.Length.ToString());
Response.ContentType = "text/plain";
Response.AppendHeader("Content-Disposition", "attachment;filename=\"output.txt\"");
Response.Write(text);
Response.End();
}
Edit 1: added more details
Edit 2: I was reading other SO posts where users were recommending to put quotes around the filename:
Response.AppendHeader("content-disposition", "attachment;filename=\"output.txt\"");
Source:
https://stackoverflow.com/a/12001019/558486
If that's your actual code, you never write the text to the response stream, so the browser never receives any data.
At the very least, you should need
Response.Write(sb.ToString());
to write your text data to the response. Also, as an added bonus, if you know the length beforehand you should provide it using the Content-Length header so the browser can show the download progress.
You're also setting Response.Buffer = true; as part of your method but never explicitly flush the response to send it to the browser. Try adding a Response.Flush() after your write statement.
I have a popup window that displays "Please wait while your file is being downloaded". This popup also executes the code below to start the file download. How can I close the popup window once the file download has completed? I need some way to detect that the file download has completed so I can call self.close() to close this popup.
System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ClearHeaders();
System.Web.HttpContext.Current.Response.ContentType = fileObject.ContentType;
System.Web.HttpContext.Current.Response.AppendHeader("Content-Disposition", string.Concat("attachment; filename=", fileObject.FileName));
System.Web.HttpContext.Current.Response.WriteFile(fileObject.FilePath);
Response.Flush();
Response.End();
An idea:
If you handle the file downloading yourself in server side code by writing chunk by chunk to the response stream, then you'll know when the file had finished downloading. You would simply have to connect the FileStream to the response stream, send data chunk by chunk, and redirecting after complete. This can be inside your popup window.
Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-disposition", "attachment; filename=bob.mp3");
Response.AppendHeader("content-length", "123456789");
Make sure you check Response.IsClientConnected when writing out to the response stream.
There is a solution where you can track the download status by transferring the file as smaller packets and check whether all the packets have been transferred.
The solution is not mine but you can find it here:
File Download in ASP.NET and Tracking the Status of Success/Failure of Download
//Function for File Download in ASP.Net in C# and
//Tracking the status of success/failure of Download.
private bool DownloadableProduct_Tracking()
{
//File Path and File Name
string filePath = Server.MapPath("~/ApplicationData/DownloadableProducts");
string _DownloadableProductFileName = "DownloadableProduct_FileName.pdf";
System.IO.FileInfo FileName = new System.IO.FileInfo(filePath + "\\" + _DownloadableProductFileName);
FileStream myFile = new FileStream(filePath + "\\" + _DownloadableProductFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//Reads file as binary values
BinaryReader _BinaryReader = new BinaryReader(myFile);
//Ckeck whether user is eligible to download the file
if (IsEligibleUser())
{
//Check whether file exists in specified location
if (FileName.Exists)
{
try
{
long startBytes = 0;
string lastUpdateTiemStamp = File.GetLastWriteTimeUtc(filePath).ToString("r");
string _EncodedData = HttpUtility.UrlEncode(_DownloadableProductFileName, Encoding.UTF8) + lastUpdateTiemStamp;
Response.Clear();
Response.Buffer = false;
Response.AddHeader("Accept-Ranges", "bytes");
Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
Response.AppendHeader("Last-Modified", lastUpdateTiemStamp);
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment;filename=" + FileName.Name);
Response.AddHeader("Content-Length", (FileName.Length - startBytes).ToString());
Response.AddHeader("Connection", "Keep-Alive");
Response.ContentEncoding = Encoding.UTF8;
//Send data
_BinaryReader.BaseStream.Seek(startBytes, SeekOrigin.Begin);
//Dividing the data in 1024 bytes package
int maxCount = (int)Math.Ceiling((FileName.Length - startBytes + 0.0) / 1024);
//Download in block of 1024 bytes
int i;
for (i = 0; i < maxCount && Response.IsClientConnected; i++)
{
Response.BinaryWrite(_BinaryReader.ReadBytes(1024));
Response.Flush();
}
//if blocks transfered not equals total number of blocks
if (i < maxCount)
return false;
return true;
}
catch
{
return false;
}
finally
{
Response.End();
_BinaryReader.Close();
myFile.Close();
}
}
else System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(),
"FileNotFoundWarning","alert('File is not available now!')", true);
}
else
{
System.Web.UI.ScriptManager.RegisterStartupScript(this, GetType(),
"NotEligibleWarning", "alert('Sorry! File is not available for you')", true);
}
return false;
}
Even though this is an old question it hasn't been answered all this time and I believe it deserves a (better) answer:
https://stackoverflow.com/a/59010319/313935
Some hacks are around that involves knowing when the last piece of the buffer has been sent or checking the HttpResponse.IsClientConnected property.
The way to do that is in your pop-up to call the server via AJAX polling for some response which would indicate the file was flushed.
Ex: right before sending the file, store sessionID+FileName in a DB or session or what have you.
On the client, in your popup, poll a web-service via AJAX - this could even be a WebMethod like Bool IsContentFlushed(string sessionID, string fileName);
After you do Response.Flush(); remove this sessionID+FileName from your store.
Call Response.Close() instead of Response.End() - the later is very brutal, and is usually over-kill.
I handle the problem differently in Javascript, which might or might not work for you.
Create a hidden DIV element, with the
message 'File is downloading...'
rather than a pop-up box.
Show the div when the download
starts
Once any other element on the
forms is clicked, hide the div
again..
You could also set a timer to hide
the download message div after so
amount of time...
I figure once the user clicks on another element, she either already knows the download is done, or she is ready to do something else, so the message becomes irrelevant and can go away....
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();
}
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
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
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.
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.
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.
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.
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".
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();
}
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.
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.