Download Document in the right format without MIME - c#

I have got this WebService that allows uploading/downloading any docs (mostly .docx, .doc, .pdf) and all it returns is byte[] when querying for downloading.
I have written this code
string ContractGUID = dtContract.Rows[0]["ContractGUID"].ToString();
//Get Bytes from WebService
byte[] fileData = BLL.Contract.GetDocument(new Guid(ContractGUID));
Response.Clear();
Response.BinaryWrite(fileData);
Response.AddHeader("Content-Disposition", "Attachment");
Response.Flush();
The other methods that the WebService exposed are GetDocumentName and GetDocumentLen
Is it possible to determine the Mime-Type or force the browser to download it in the right format? Currently it is downloading as .htm in Chrome and when open, I see funny characters. Any better advice?
Thanks.

No, it's not possible to force the browser to download in the right format without you telling it via the Content-Type header.
Response.ContentType = "application/pdf"; //or whatever appropriate
If the web service exposes a GetDocumentName() method you can probably infer the appropriate format by looking at the name, assuming the name has a file extension. This, obviously, is not bullet proof since you can change the extension of a file to anything you want.
Another alternative would be to try and guess the file format by peeking at the first bytes. For example, if the first 4 bytes of the file are 25 50 44 46 then it's very likely that this is a PDF file. On this website, they have a pretty extensive list.
Here's the list of possible content-type headers.

I think, the browser does it through filename.
e.g.:
response.Clear();
response.AddHeader("Content-Disposition", "attachment; filename=" + dbFile.filename.Replace(" ", "_"));
response.AddHeader("Content-Length", dbFile.data.Length.ToString());
response.ContentType = "application/octet-stream";
response.OutputStream.Write(dbFile.data, 0, dbFile.data.Length);
response.End();
dbFile.filename is a string
dbFile.data is a byte[]

Related

What is the correct Excel Application type? [duplicate]

I use CarlosAG-Dll which creates a XML-Excel-file for me (inside a MemoryStream).
Response.ContentType = "application/vnd.ms-excel";
Response.AppendHeader("content-disposition", "myfile.xml");
memory.WriteTo(Response.OutputStream);
My Problem here is, that I get at client side a myfile.xls (IE) or a myfile.xml.xls (FF) and therefore get an annoying security warning from excel.
I tried it as well with application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (xlsx) but then it won't even open.
So I need to either cut the .xml and send it as vnd.ms-excel (how?) or take another MIME-type (but which one?).
edit: I found a bug description here
I wonder if this is still open and why?
Use like this
Response.ContentType = "application/vnd.ms-excel";
Response.AppendHeader("content-disposition", "attachment; filename=myfile.xls");
For Excel 2007 and above the MIME type differs
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("content-disposition", "attachment; filename=myfile.xlsx");
See list of MIME types
Office 2007 File Format MIME Types
EDIT:
If the content is not a native Excel file format, but is instead a
text based format (such as CSV, TXT, XML), then the web site can add
the following HTTP header to their GET response to tell IE to use an
alternate name, and in the name you can set the extension to the right
content type:
Response.AddHeader "Content-Disposition", "Attachment;Filename=myfile.csv"
For more details see this link
If your document is an Excel Xml 2003 document, you should use the text/xml content type.
Response.ContentType = "text/xml";
Do not specifiy content-disposition.
This technichs works great with Handler, not with WebForm.
The security warning is NOT about the MIME type - it is a client-side security setting you can't disable from the server side !
Another point - change Response.AppendHeader("content-disposition", "myfile.xml"); to:
Response.AppendHeader("content-disposition", "attachment; filename=myfile.xlsx");
OR
Response.AppendHeader("content-disposition", "inline; filename=myfile.xlsx");
For reference see http://www.ietf.org/rfc/rfc2183.txt
EDIT - as per comment:
IF the format is not XLSX (Excel 2007 and up) then use myfile.xls in the above code.

ASP.NET MVC cannot stream files

I have a ASP.NET MVC 4 site that creates an excel file using OPEN XML SDK. I simply point the hyperlink to the proper controller and it generates the OPEN XML excel document and writes the stream to response header and done. In IE 9 and Chrome this works fine. File gets downloaded with the given file name and proper contents. However, just recently I upgraded my browser to IE 10 and now instead of downloading the file and opening up in excel I get the error that could not open 'URI'. When I click ok it gives another error: Microsoft Excel cannot access the file 'URI'. There are several possible reasons:
I don't understand why this would work in IE 9 and chrome and not in IE 10. I debugged the response headers with fiddlers and it has the proper content type, and content length set:
Content Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content Disposition: attachment; filename=result.xlsx
Content length: 1232
Is there something that I am missing?
Code snippet: This all is part of
public override void ExecuteResult(ControllerContext context)
{
...
....
..
extention = "xlsx";
response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
response.AddHeader("Content-Disposition",
String.Format("attachment; filename={0}.{1}", fileName, extention));
response.AddHeader("Content-Length", mem.Length.ToString());
mem.Seek(0, SeekOrigin.Begin); // Go back to the begining.
mem.CopyTo(response.OutputStream);
context.HttpContext.ApplicationInstance.CompleteRequest();
}
As a workaround, Controller.File works for me with ASP.NET MVC 4 and IE 10:
public class DownloadController : Controller
{
public ActionResult GetFile()
{
...
mem.Position = 0;
return File(
mem,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"result.xlsx");
}
}
EDIT
So I have been browsing the MVC source code at CodePlex and found a few implementation details that differ from your code snippet:
Content-Length header is never set
Instead of calling Stream.CopyTo, they use a simple Stream.Read, Stream.Write loop with buffer size of 0x1000
When setting Content-Disposition header, they check whether file download name contains UTF-8 chars, and if so, encode them according to RFC 2231. See ContentDispositionUtil.GetHeaderValue
context.HttpContext.ApplicationInstance.CompleteRequest() is never called
Now you could try applying these changes one by one and see which one makes it work with IE 10.
I guess it's an IE10 bug. But maybe you still can work around it.
Based on this post and a few others.
Please check that:
Both full URI and the filename of Content Disposition header do not contains special symbols and that their lengths are less than 105. Just use regular A-Za-z0-9 symbols for instance.
Try to add "X-UA-Compatible" HTTP header with "IE=9" value.
try these MIME types:-
for old version:-
Response.ContentType = "application/vnd.ms-excel";
Response.AppendHeader("content-disposition", "attachment; filename=myfile.xls");
for 2007:-
Response.ContentType = "application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("content-disposition", "attachment; filename=result.xlsx");
for csv files which you need to open in excel is:-
Response.AddHeader "Content-Disposition", "Attachment;Filename=myfile.csv"
in last you can try:-
Response.ContentType = "application/octet-stream";
Response.AppendHeader("content-disposition", "attachment; filename=result.xlsx");
thanks

.net CSV file stream to browser loosing characters on production server

I've got basic functionality to stream a file to the browser which invokes a "Save As". The output is dynamically generated and stored within a string and not a file saved on the server.
See code below.
string output = GenerateCSVDdata;
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "attachment; filename=\"test.csv\");
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble());
Response.Write(output);
Response.End();
Now, on my development server, the CSV fully downloads. On the production server, the last few characters on end are cut off. The larger the CSV, the more characters are missing. I've tried so many different things like Response.Flush etc but nothing can fix it. The only thing I can do is throw a load of empty chars on the end in hope nothing gets cut.
Is there something quite wrong with this method of streaming a file download without actually saving the file to disk?
Thanks for your help.
Can you determine if there is a difference in the byte count for the .csv file you are using?
byte[] defaultEncodingBytes = System.Text.Encoding.Default.GetBytes(defaultEncodingFileContents);
byte[] UTF8EncodingBytes = System.Text.Encoding.UTF8.GetBytes(defaultEncodingFileContents);
Try this, it worked for me.
void DownloadFile(string filename)
{
//string filename = "c:\\temp\\test.csv";
byte[] contents = System.IO.File.ReadAllBytes(filename);
Response.Clear();
Response.ClearHeaders();
Response.AppendHeader("Content-disposition", String.Format("attachment; filename=\"{0}\"", System.IO.Path.GetFileName(filename)));
Response.AppendHeader("Content-Type", "binary/octet-stream");
Response.AppendHeader("Content-length", contents.Length.ToString());
Response.BinaryWrite(contents);
if (Response.IsClientConnected)
Response.Flush();
}
Regards.

MIME-Type for Excel XML (ASP.NET 3.5)

I use CarlosAG-Dll which creates a XML-Excel-file for me (inside a MemoryStream).
Response.ContentType = "application/vnd.ms-excel";
Response.AppendHeader("content-disposition", "myfile.xml");
memory.WriteTo(Response.OutputStream);
My Problem here is, that I get at client side a myfile.xls (IE) or a myfile.xml.xls (FF) and therefore get an annoying security warning from excel.
I tried it as well with application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (xlsx) but then it won't even open.
So I need to either cut the .xml and send it as vnd.ms-excel (how?) or take another MIME-type (but which one?).
edit: I found a bug description here
I wonder if this is still open and why?
Use like this
Response.ContentType = "application/vnd.ms-excel";
Response.AppendHeader("content-disposition", "attachment; filename=myfile.xls");
For Excel 2007 and above the MIME type differs
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("content-disposition", "attachment; filename=myfile.xlsx");
See list of MIME types
Office 2007 File Format MIME Types
EDIT:
If the content is not a native Excel file format, but is instead a
text based format (such as CSV, TXT, XML), then the web site can add
the following HTTP header to their GET response to tell IE to use an
alternate name, and in the name you can set the extension to the right
content type:
Response.AddHeader "Content-Disposition", "Attachment;Filename=myfile.csv"
For more details see this link
If your document is an Excel Xml 2003 document, you should use the text/xml content type.
Response.ContentType = "text/xml";
Do not specifiy content-disposition.
This technichs works great with Handler, not with WebForm.
The security warning is NOT about the MIME type - it is a client-side security setting you can't disable from the server side !
Another point - change Response.AppendHeader("content-disposition", "myfile.xml"); to:
Response.AppendHeader("content-disposition", "attachment; filename=myfile.xlsx");
OR
Response.AppendHeader("content-disposition", "inline; filename=myfile.xlsx");
For reference see http://www.ietf.org/rfc/rfc2183.txt
EDIT - as per comment:
IF the format is not XLSX (Excel 2007 and up) then use myfile.xls in the above code.

Change name of file sent to client?

I have a webpage that pulls information from a database, converts it to .csv format, and writes the file to the HTTPResponse.
string csv = GetCSV();
Response.Clear();
Response.ContentType = "text/csv";
Response.Write(csv);
This works fine, and the file is sent to the client with no problems. However, when the file is sent to the client, the name of the current page is used, instead of a more friendly name (like "data.csv").
My question is, how can I change the name of the file that is written to the output stream without writing the file to disk and redirecting the client to the file's url?
EDIT: Thanks for the responses guys. I got 4 of the same response, so I just chose the first one as the answer.
I believe this will work for you.
Response.AddHeader("content-disposition", "attachment; filename=NewFileName.csv");
You just need to set the Content-Disposition header
Content-Disposition: attachment; filename=data.csv
This Microsoft Support article has some good information
How To Raise a "File Download" Dialog Box for a Known MIME Type
Add a "Content-Disposition" header with the value "attachment; filename=filename.csv".
Response.AddHeader("content-disposition", "attachment; filename=File.doc")

Categories