0

ダウンロード用のファイルを提供する汎用ハンドラーがあります。

    Dim request As HttpRequest = context.Request
    Dim response As HttpResponse = context.Response
    response.ContentType = "application/octet-stream"
    response.AddHeader("content-disposition", "inline; filename=" & filename)
    response.Buffer = True
    response.OutputStream.Write(fileBytes, 0, fileBytes.Length)
    response.Flush()
    response.Close()

(「fileBites」はバイト配列、「filename」はファイル名)。

たとえば、fileBites が .txt ファイルの場合、ダウンロードが開始され、ファイルは完全に読み取られます。

しかし、.pdf ファイルと .docx ファイルが破損していることに気付きました。.docx の場合、Word はファイルを復元する必要があると言って、復元の許可を求めてきました。この許可を与えると、すぐに修正され、完全に表示されました。

明らかに、私はユーザーにこの破損ダイアログを見せたくなかったので、しばらく調査した後、これを発見しました: http://forums.asp.net/t/1301978.aspx/1/10 - これは、破損の理由を示唆しています余分な空のビットがバイト配列の最後に書き込まれていました: 長さを 1 ビット落として確認しました:

response.OutputStream.Write(fileBytes, 0, fileBytes.Length - 1)

魔法のように、.docx のダウンロードが機能するようになりました。(これは私の現在の問題ではありません。コンテキストと他の誰かが同じ問題を抱えている場合に備えて含めます)

私の現在の問題は、.docx ファイルは正しくストリーミングされるようになりましたが、.pdf ファイルは正しくないことです。それらは (正しい KB サイズで) 1 つにまとめて転送されるように見えますが、ダウンロードしたファイルを開こうとすると、Adobe Reader X から次のように表示されます。

Adobe Reader could not open xxxx because it is either not a supported file type 
or because the file has been damaged (for example, it was sent as an email 
attachment and wasn't correctly decoded).

2008 年付けの adobe フォーラム ( http://forums.adobe.com/thread/391712 ) で、この正確な問題に対処するためのかなり長い未解決の議論がありましたが、これは現在死んでいます。ユーザーが投稿したすべての回避策 (コンテンツ タイプ: /pdf ではなく /octet、配置: アプリケーションがインラインではない、コンテンツ エンコーディングと文字セットが異なるなど) をすべて試しましたが、すべて役に立ちませんでした。

誰かがこの問題に遭遇した前に、どこか漠然としたものをどこかで指摘して、正しい方向に少しでも似ているかどうか疑問に思います!

4

1 に答える 1

0

(コメントと編集で回答してください。回答がない質問を参照してください。ただし、コメントで問題が解決されています(またはチャットで拡張されています)

OP は次のように書いています。

何時間もじっと見つめていたので、この質問を投稿した直後に答えが現れました - これはよくあることです! とにかく、これが私の特定の問題で立ち往生している他の人のための解決策です:

ファイルをデータベースに追加したときに、名前を変更できるようにもしました。ファイルを選択し、名前を付けてDBに[Fileblob],[Filename]保存します。ファイルシステムの特定の場所に関連付けられなくなったため、任意の名前を選択できると思いました。- 違う!- .txt および .docx ファイルでは問題なく、元の名前が呼び出されることはありませんでした。

明らかに、ファイルが保存されたときに何かがバイナリ オブジェクトにファイルの名前を埋め込んでおり、ドキュメントが開かれたときに content-disposition で提供された名前をドキュメントに埋め込まれた名前と照合します。一致しない場合は、破損エラーがスローされます。

今、私はファイルをデータベースに保存しており、[Fileblob],[Filename],[originalFilename]それを開くときに使用しています:

response.AddHeader("content-disposition", "inline;filename=" & originalFilename)

..わかりやすい名前を付けます。より洗練された方法は、PDF をデータベースに保存するときに不要になったため、元の名前を PDF から削除することだと思いますが、回避策としてこれは問題なく機能します。

于 2015-01-26T22:27:59.753 に答える