如何返回MemoryStream docx文件MVC?

MrM*_*MrM 10 c# asp.net-mvc file-upload docx asp.net-mvc-3

我有一个docx文件,我想在编辑后返回.我有以下代码......

object useFile = Server.MapPath("~/Documents/File.docx");
object saveFile = Server.MapPath("~/Documents/savedFile.docx");
MemoryStream newDoc = repo.ChangeFile(useFile, saveFile);
return File(newDoc.GetBuffer().ToArray(), "application/docx", Server.UrlEncode("NewFile.docx"));
Run Code Online (Sandbox Code Playgroud)

该文件似乎很好,但我收到错误消息("文件已损坏"和另一个说"Word发现不可读的内容.如果您信任源点击是").有任何想法吗?

提前致谢

编辑

这是我模型中的ChangeFile ......

    public MemoryStream ChangeFile(object useFile, object saveFile)
    {
        byte[] byteArray = File.ReadAllBytes(useFile.ToString());
        using (MemoryStream ms = new MemoryStream())
        {
            ms.Write(byteArray, 0, (int)byteArray.Length);
            using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(ms, true))
            {                    
                string documentText;
                using (StreamReader reader = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
                {
                    documentText = reader.ReadToEnd();
                }

                documentText = documentText.Replace("##date##", DateTime.Today.ToShortDateString());
                using (StreamWriter writer = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
                {
                    writer.Write(documentText);
                }
            }
            File.WriteAllBytes(saveFile.ToString(), ms.ToArray());
            return ms;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Par*_*ker 13

我使用FileStreamResult:

var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = fileName,

        // always prompt the user for downloading, set to true if you want 
        // the browser to try to show the file inline
        Inline = false,
    };
Response.AppendHeader("Content-Disposition", cd.ToString());

return new FileStreamResult(documentStream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
Run Code Online (Sandbox Code Playgroud)


Llo*_*oyd 10

不要MemoryStream.GetBuffer().ToArray()使用MemoryStream.ToArray().

其原因GetBuffer()与用于创建存储器流的数组有关,而与存储器流中的实际数据无关.底层阵列的大小实际上可能不同.

隐藏在MSDN上:

请注意,缓冲区包含可能未使用的已分配字节.例如,如果将字符串"test"写入MemoryStream对象,则从GetBuffer返回的缓冲区长度为256而不是4,未使用252个字节.要仅获取缓冲区中的数据,请使用ToArray方法; 但是,ToArray会在内存中创建数据副本.