I'm trying to send an xlsx file by using
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "application/vnd-ms.excel";
Response.TransmitFile(file.FullName);
Response.End();
The IE dialog pops up and I can successfully save the file, then open it from the folder, that works fine and dandy. But if I click on "Open" in the IE dialog, I get a "myFile.xlsx couldn't be downloaded." I click on "Retry" and it opens Excel but pops up the "Excel cannot open the file 'myFile.xlsx' because the file format or file extension is not valid..." error.
I'm currently running the site from VS2010 in debug mode.
Does anybody know why it would let me save, but not open directly?
Edit
Chrome just downloads it. FF tried opening it but gives the error The file you are trying to open, 'myFile.xlsx.xls', is in a different format than specified by the file extension... I can choose to open it anyways and it successfully opens, but in readonly mode.
So, something funky is going on here.
fileName = "myFile.xlsx"
Edit 2
This is in IE 9. I've also tried octet-stream and application/vnd.openxmlformats-officedocument.spreadsheetml.sheet as the ContentType.
It is because your ContentType is wrong. Use
Response.ContentType = "application/vnd.ms-excel";
Edit
if it didnt work, can you try
FileStream sourceFile = new FileStream(file.FullName, FileMode.Open);
float FileSize;
FileSize = sourceFile.Length;
byte[] getContent = new byte[(int)FileSize];
sourceFile.Read(getContent, 0, (int)sourceFile.Length);
sourceFile.Close();
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Length", getContent.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.BinaryWrite(getContent);
Response.Flush();
Response.End();
I had the same problem once, and solved by revising caching instructions sent by application server, in this case, IIS. Sometimes you add headers at application level that prevents the file from being saved in some conditions, like in HTTPS connections. Make sure that you aren't putting conflicting instructions.
I ran into similar issue.
Turned out I was reading from end of the stream so, the byte array wasn't getting filled with anything.
Setting the stream position to 0 (sourceFile.Position=0;) just before reading the stream (sourceFile.Read(getContent, 0, (int)sourceFile.Length);) fixed it for me.
See if that helps.
As for "Response.ContentType", "application/vnd.ms-excel" worked for me.
FileStream sourceFile = new FileStream(file.FullName, FileMode.Open);
float FileSize;
FileSize = sourceFile.Length;
byte[] getContent = new byte[(int)FileSize];
sourceFile.Position=0;
sourceFile.Read(getContent, 0, (int)sourceFile.Length);
sourceFile.Close();
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Length", getContent.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.BinaryWrite(getContent);
Response.Flush();
Response.End();
By coincidence I'm right in the middle of something similar...
The MIME type to use for xlsx is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, see this question.
I was stumped by this issue, particularly with longer files.
Turned out in our case using the Content-Length header fixed the issue. Once the content gets over a certain length, you get this issue.
Example (where tempsbldr is a StringBuilder):
Response.AddHeader("Content-Length",tempsbldr.Length.ToString());
Related
I inherited an .net application that allows users to download a pdf. Now, I am able to download the pdf file when I run locally but when I deploy to IIS server I run into problems. The download works on Firefox but doesnt work on Chrome, and sometimes on IE. The fact that I can download it on my local development environment tells that it could be something with IIS configuration or maybe my code. The pdf is stored in ms sql server 2012 table as varbinary. I provided some code below that is used to read the data. Please let me know if there are other information you all need. Also, I checked the iis logs and I am getting 200 status codes for everything. Nothing stands out in there.
if(Session["DetailID"] != null)
{
//get the file
DataTable dt = sp_Attachment_Download(lblAttachmentIDD.Text);
DataRow row = dt.Rows[0];
string name = (string)row["AFileName"];
string contentType = (string)row["AFileType"];
Byte[] data = (Byte[])row["AFile"];
/// Send the file to the browser
Response.AddHeader("Content-type", contentType);
Response.AddHeader("Content-Disposition", "attachment; filename=" + name);
Response.BinaryWrite(data);
Response.Flush();
Response.Close();
}
EDITED----------
I am using the developer tools for IE and Chrome and found something interesting. Chrome gives me the following error when I click on the link:
interpreted as Document but transferred with MIME type application/pdf:
IE doesnt give an error but something caught my attention. I my REQUEST header, ACCEPT does not contain application/pdf and the RESPONSE Content-Type has application/pdf. Could this be something? How can I set the ACCEPT to include application/pdf in aspx page?
I had kinda similar issue when downloading pdf from chrome as in my case filename had a comma in it and that chrome apparently didn't like it, so I removed comma from filename and it worked.
PS: Please try not to use Response.Close(). It aborts the thread and throws exception.
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=" + fileName.Replace(",",,");
Response.CacheControl = "No-cache";
Response.Write(data);
Response.Flush();
Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
Maybe this will help, here's my code to do the same thing. One thing that I noticed is that you're not specifying the file length, which I believe is required. Please note that pFileData is class that contains FileName, a string, and FileData, a byte[].
System.Web.HttpResponse Response = System.Web.HttpContext.Current.Response;
Response.Clear();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=" + pFileData.FileName);
Response.AddHeader("Content-Length", pFileData.FileData.Length.ToString());
Response.BufferOutput = false;
Response.BinaryWrite(pFileData.FileData);
Response.Flush();
Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
Response.End();
I tried to get a pdf file opened in chrome but it seems to be stuck in the middle of somewhere during displaying process. The code seems to work because it can get PDF opened in IE, not sure why it got stuck in chrome. The screen will just grey out, show the "LOADING" sign, and stop at 7/8. The file is around 6MB or more.
public static void ReturnPDF(byte[] contents)
{
var response = HttpContext.Current.Response;
response.Clear();
response.AppendHeader("Content-Disposition", "inline;filename=" + "abc.pdf");
response.BufferOutput = true;
response.ContentType = System.Net.Mime.MediaTypeNames.Application.Pdf;
response.BinaryWrite(contents);
response.Flush();
response.Close();
response.End();
}
Any thoughts? Thanks
[UPDATE]
I tried firefox with version 30.0 and it WORKS. My IE is 8.0.7601.17514, which can also open pdf. My Chrome is 39.0.2171.95. Not sure wheather the version of the browser matters or not, here only chrome fails to open the inline PDF...
[SOLVED]
After adding content-length, chrome can open the inline PDF.
public static void ReturnPDF(byte[] contents)
{
var response = HttpContext.Current.Response;
response.Clear();
response.AppendHeader("Content-Disposition", "inline;filename=" + "abc.pdf");
//After adding Content-Length, chrome is able to open PDF inline
response.AppendHeader("Content-Length", contents.Length.ToString());
response.BufferOutput = true;
response.ContentType = System.Net.Mime.MediaTypeNames.Application.Pdf;
response.BinaryWrite(contents);
response.Flush();
response.Close();
response.End();
}
The OP's original code created the response like this:
response.Clear();
response.AppendHeader("Content-Disposition", "inline;filename=" + "abc.pdf");
response.BufferOutput = true;
response.ContentType = System.Net.Mime.MediaTypeNames.Application.Pdf;
response.BinaryWrite(contents);
response.End();
This code especially does not set the Content-Length header. Some web browser versions (not only Chrome but also certain versions of other browsers) without that header tend to prematurely consider the download finished.
Detecting when a download is finished on a connection initially created as persistent, may not be trivial if neither a non-identity Transfer-Encoding nor a Content-Length has been supplied.
Thus, the solution here is to add
response.AppendHeader("Content-Length", contents.Length.ToString());
before writing the contents.
Try with "Content-disposition: attachment" header.
Thanks mkl's suggestions.
I added the content length in the header and the pdf can be successfully opened in Chrome!
I have an ASP.NET page and a c# method that takes a memorystream (of an excel-file) and then uses the HTTPResponse-class to stream this file, in binary, to the browser.
public static void WriteStreamToBrowser(MemoryStream streamExcelFile, string filename, bool isResponseEnd = false)
{
System.Web.HttpResponse Response = System.Web.HttpContext.Current.Response;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", filename));
Response.Clear();
Response.BinaryWrite(streamExcelFile.GetBuffer());
}
Now this method works FINE when I use my asp.net page in Firefox or Chrome. They neatly trigger the websites "do you want to download this file" feature.
However, when using IE11, the browser window instantly closes but the "do you want to download this file?" dialog actually pops up and remains.
I'm guessing that IE needs some special treatment when it comes to the Response-methods but I haven't been able to figure out what I do wrong.
How do I change the above method so that will also work with IE11?
--
Let me know if you need any extra details!
EDIT:
Worth mentioning is that debugging does not throw any exceptions.
Also, the dialoge that pops up is actually the download history.
EDIT 2:
I've tried to follow some advice from other guides and added some stuff. Still, resultat is the same.
public static void WriteStreamToBrowser2(MemoryStream streamExcelFile, string filename, bool isUseNewExcel = true)
{
System.Web.HttpResponse Response = System.Web.HttpContext.Current.Response;
string contentType = isUseNewExcel ? "application/vnd.ms-excel" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", filename));
Response.AddHeader("content-length", streamExcelFile.Length.ToString());
Response.AddHeader("content-type", contentType);
Response.BinaryWrite(streamExcelFile.GetBuffer());
//to avoid ThreadAbortion
Response.Flush();
Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
Response.Close();
}
Alright, I managed to solve the broken excel download by adding a +".xls" to the file name. Why IE but not Chrome and Firefox requires you to explicitly define the extension in the filenamestring, I will never know. To be clear, this did not solve my problem with IE closing my main window but that's not an issue right now.
So i have a PDF file on my server, i can open it up and it looks fine.
I then try to serve the file with this code
Response.ContentType = "Application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=Filename.pdf");
Response.TransmitFile("C:\\Temp\\Filename.pdf");
Response.End();
This serves the file, it saves on the client, but the problem is this new file is about .05Mb larger than the original, and when you try to open it the PDF is corrupt.
Any ideas?
Your code should work. Please make sure you are using Ajax for downloading file.
You can try using flash and close before end.
Response.ContentType = "Application/pdf";
Response.AppendHeader("Content-Disposition", "attachment; filename=Filename.pdf");
Response.TransmitFile("C:\\Temp\\Filename.pdf");
Response.Flush();
Response.Close();
Response.End();
If it still doesn't work, you can try BinaryWrite. The only disadvantage is that it doesn't work well with large file because it loads the file to memory before sending to client.
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=Filename.pdf"));
Response.BinaryWrite(File.ReadAllBytes("C:\\Temp\\Filename.pdf"));
Response.End();
I am trying to open a PDF document to display within IE6. I am using the following snippet:
response.ContentType = healthMedia.MediaKey.MimeType;
response.ClearHeaders();
response.AddHeader("Content-Disposition", "inline; filename=" + mediaKeyId);
int contentLength = healthMedia.Content.Length;
response.AppendHeader("content-length", Convert.ToString(contentLength));
response.OutputStream.Write(healthMedia.Content, 0, contentLength);
healthMedia.MediaKey.MimeType; is equal to 'application/pdf'
This brings up the Save dialog. If I comment out Response.ClearHeaders(); I get a new window to popup but it's contents is a bunch of jibberish (random encoding text).
How can I get IE6 to open the PDF correctly?
-Nick
Have you tried Response.End() and also Response.Buffer = true? You may also need to set a caching policy.
In case it helps, here's a method I've used before to render in-browser PDFs...
Use response.BinaryWrite() instead of response.OutputStream.Write()