I have this following code for bringing page attachments to the user:
private void GetFile(string package, string filename)
{
var stream = new MemoryStre
When storing a binary file in SQL Server, keep in mind that a file is padded to the nearest word boundry, so you can potentially have an extra byte added to a file. The solution is to store the original file size in the db when you store the file, and use that for the length that needs to be passed to the write function of the Stream object. "Stream.Write(bytes(), 0, length)". This is the ONLY reliable way of getting the correct file size, which is very important for Office 2007 and up files, which do not allow extra characters to be on the end of them (most other file types like jpg's don't care).
Take a look a this: Writing MemoryStream to Response Object
I had the same problem and the only solution that worked for me was:
Response.Clear();
Response.ContentType = "Application/msword";
Response.AddHeader("Content-Disposition", "attachment; filename=myfile.docx");
Response.BinaryWrite(myMemoryStream.ToArray());
// myMemoryStream.WriteTo(Response.OutputStream); //works too
Response.Flush();
Response.Close();
Response.End();
I had the same problem while i try to open .docx and .xlsx documents. I solve the problem by defining the cacheability to ServerAndPrivate instead of NoCache
there is my method to call document:
public void ProcessRequest(HttpContext context)
{
var fi = new FileInfo(context.Request.Path);
var mediaId = ResolveMediaIdFromName(fi.Name);
if (mediaId == null) return;
int mediaContentId;
if (!int.TryParse(mediaId, out mediaContentId)) return;
var media = _repository.GetPublicationMediaById(mediaContentId);
if (media == null) return;
var fileNameFull = string.Format("{0}{1}", media.Name, media.Extension);
context.Response.Clear();
context.Response.AddHeader("content-disposition", string.Format("attachment;filename={0}", fileNameFull));
context.Response.Charset = "";
context.Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);
context.Response.ContentType = media.ContentType;
context.Response.BinaryWrite(media.Content);
context.Response.Flush();
context.Response.End();
}
I also ran into this problem and actually found the answer here: http://www.aspmessageboard.com/showthread.php?t=230778
It turns out that the docx format needs to have Response.End() right after the Response.BinaryWrite.
You should not use stream.GetBuffer()
because it returns the buffer array which might contain unused bytes. Use stream.ToArray()
instead. Also, have you tried calling stream.Seek(0, SeekOrigin.Begin)
before writing anything?
Best Regards,
Oliver Hanappi
If you use the approach above which uses response.Close(), Download managers such as IE10 will say 'cannot download file' because the byte lengths do not match the headers. See the documentation. Do NOT use response.Close. EVER. However, using the CompeteRequest verb alone does not shut off the writing of bytes to the ouput stream so XML based applications such as WORD 2007 will see the docx as corrupted. In this case, break the rule to NEVER use Response.End. The following code solves both problems. Your results may vary.
'*** transfer package file memory buffer to output stream
Response.ClearContent()
Response.ClearHeaders()
Response.AddHeader("content-disposition", "attachment; filename=" + NewDocFileName)
Me.Response.ContentType = "application/vnd.ms-word.document.12"
Response.ContentEncoding = System.Text.Encoding.UTF8
strDocument.Position = 0
strDocument.WriteTo(Response.OutputStream)
strDocument.Close()
Response.Flush()
'See documentation at http://blogs.msdn.com/b/aspnetue/archive/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation.aspx
HttpContext.Current.ApplicationInstance.CompleteRequest() 'This is the preferred method
'Response.Close() 'BAD pattern. Do not use this approach, will cause 'cannot download file' in IE10 and other download managers that compare content-Header to actual byte count
Response.End() 'BAD Pattern as well. However, CompleteRequest does not terminate sending bytes, so Word or other XML based appns will see the file as corrupted. So use this to solve it.
@Cesar: you are using response.Close--> can you try it with IE 10? bet it doesn't work (byte counts don't match)