ASP.NETページからダウンロードする際に、なぜの.docxファイルが壊れてされていますか?

StackOverflow https://stackoverflow.com/questions/2477564

  •  21-09-2019
  •  | 
  •  

質問

私は、ユーザーにページの添付ファイルをもたらすため、この次のコードを持っています:

private void GetFile(string package, string filename)
{
    var stream = new MemoryStream();

    try
    {
        using (ZipFile zip = ZipFile.Read(package))
        {
            zip[filename].Extract(stream);
        }
    }
    catch (System.Exception ex)
    {
        throw new Exception("Resources_FileNotFound", ex);
    }

    Response.ClearContent();
    Response.ClearHeaders();
    Response.ContentType = "application/unknown";

    if (filename.EndsWith(".docx"))
    {
        Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    }

    Response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
    Response.BinaryWrite(stream.GetBuffer());
    stream.Dispose();
    Response.Flush();
    HttpContext.Current.ApplicationInstance.CompleteRequest();
}
問題は、サポートされているすべてのファイルが(JPG、GIF、PNG、PDF、DOCなど)を適切に動作しますが、.docxのファイルは、ダウンロードした際に、破損していると、彼らがオープンするために、オフィスで固定する必要があるということです。

問題は.docxのを含んでいたzipファイルを解凍にあった場合、私はので、最初のIで

は、その代わりにのみ応答して出力ファイルを置くことで、私が最初にそれを保存し、ファイルが正常に開かれ、知りませんでした問題は、応答の書き込みでなければなりません知っています。

あなたが起こってできるか知っていますか?

役に立ちましたか?

解決

私もこの問題に遭遇した、実際にここで答えを見つけました:のhttp:// WWW .aspmessageboard.com / showthread.php?トン= 230778

これは、DOCX形式は右Response.BinaryWrite後Response.Endの()を持っている必要があることが判明します。

他のヒント

SQL Serverでバイナリファイルを保存するときに、あなたが潜在的にファイルに追加し、余分なバイトを持つことができますので、

、ファイルは最寄りのワードboundryに埋められていることに注意してください。ソリューションは、ファイルを保存する際にDBに元のファイルサイズを格納することで、Streamオブジェクトの書き込み関数に渡される必要がある長さのためにその使用。 "Stream.Write(バイト()、0、長さ)"。これは、Office 2007のために、余分な文字がそれらの終わりにすることはできませんファイル、アップ非常に重要であり、正しいファイルサイズ、(のjpgのような他のほとんどのファイルの種類を気にしない)を得るための唯一の信頼できる方法です。

それは、未使用のバイトが含まれている可能性があるバッファ配列を返すため、

あなたはstream.GetBuffer()を使用しないでください。使用して、代わりにstream.ToArray()。また、あなたが何かを書き込む前にstream.Seek(0, SeekOrigin.Begin)を呼び出してみましたがありますか?

よろしく、
オリバーハナッピ

何もの価値のために、私はまた、ここに記載されている同じ問題に遭遇しました。

:私にとっての問題は、アップロードのコードではありませんダウンロードコードと実際ました
    Public Sub ImportStream(FileStream As Stream)
        'Use this method with FileUpload.PostedFile.InputStream as a parameter, for example.
        Dim arrBuffer(FileStream.Length) As Byte
        FileStream.Seek(0, SeekOrigin.Begin)
        FileStream.Read(arrBuffer, 0, FileStream.Length)
        Me.FileImage = arrBuffer
    End Sub
この例では、問題は、私は大きすぎるサイズは1バイトでバイト配列arrBufferを宣言しています。このNULLバイトは、DBへのファイルの画像を保存して、ダウンロードの上に再現されます。修正されたコードは次のようになります:

        Dim arrBuffer(FileStream.Length - 1) As Byte
次のようにまた、参考のために私のHttpResponseコードがあります:

                context.Response.Clear()
                context.Response.ClearHeaders()
                'SetContentType() is a function which looks up the correct mime type
                'and also adds and informational header about the lookup process...
                context.Response.ContentType = SetContentType(objPostedFile.FileName, context.Response)
                context.Response.AddHeader("content-disposition", "attachment;filename=" & HttpUtility.UrlPathEncode(objPostedFile.FileName))
                'For reference: Public Property FileImage As Byte()
                context.Response.BinaryWrite(objPostedFile.FileImage)
                context.Response.Flush()
あなたがresponse.Closeを(使用する上でのアプローチ)を使用している場合は、

、などIE10などのダウンロードマネージャは、バイト長は、ヘッダと一致しないため、「ファイルをダウンロードすることができません」と言うだろう。マニュアルを参照してください。 response.Closeを使用しないでください。 EVER。 壊れたようなWORD 2007などのXMLベースのアプリケーションは、docxファイルが表示されますので、しかし、動詞だけではCompeteRequestを使用すると、出力に含まストリームにバイトの書き込みを切ることはできません。 この場合、Response.Endのを使用しないようにルールを破ります。次のコードは、両方の問題を解決します。あなたの結果は異なる場合があります。

        '*** 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:あなたはresponse.Closeを使用している - >あなたはIE 10でそれを試すことができますか?それは仕事(バイト数が一致しない)

ない賭けます

これは、すべてがOKになります。私の唯一のアイデアはバイトが完全にフラッシュする前に書かれていません念のため、代わりに前のResponse.Flushを呼び出した後、あなたのストリーム上のDisposeを呼び出してみることです。

このを見てみましょう:レスポンスオブジェクトに書き込みMemoryStreamをする

私は同じ問題を抱えていたし、私のために働いた唯一の解決策だった。

    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();
私はオープンの.docxや.xlsx形式の文書にしようとしながら、

私は同じ問題を抱えていました。私の代わりにNoCache命令のServerAndPrivateにキャッシュ可能性を定義することによってこの問題を解決する

私のメソッドは、呼び出し文書にあります:

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();          
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top