0

次の ActionResult があります。

[Authorize]
public ActionResult DownloadFile(Guid id)
{
    AdjusterFile file = (from f in db.AdjusterFiles
                         join a in db.Adjusters
                         on f.adjusterID equals a.id
                         join u in db.Users
                         on a.userID equals u.id
                         where u.username == HttpContext.User.Identity.Name
                         && f.id == id
                         select f)
                        .FirstOrDefault();

    return new FileContentResult(file.fileContent.ToArray(), file.fileContentType);
}

Word 文書 (DOC/DOCX) に最適です。ただし、同じプロセスでアップロードされた PDF をダウンロードしようとすると、Chrome で「PDF ドキュメントの読み込みに失敗しました」と表示されます。IE では、「ファイルが破損しているため、修復できませんでした」と表示されます。

コンテンツ タイプは「application/pdf」です。

MVC で PDF をダウンロードするにはどうすればよいですか?

関連するファイル アップロード コード:

using (MemoryStream ms = new MemoryStream())
{
    file.InputStream.CopyTo(ms);
    byte[] array = ms.GetBuffer();

    AdjusterFile newFile = new AdjusterFile();

    newFile.id = Guid.NewGuid();
    newFile.adjusterID = adj.id;
    newFile.type = "eo";
    newFile.fileName = file.FileName;
    newFile.fileContent = array;
    newFile.fileContentType = file.ContentType;

    db.AdjusterFiles.InsertOnSubmit(newFile);
}
4

1 に答える 1

3

MemoryStream は必要ありません。次のようにしてください。

byte[] array = new byte[file.ContentLength];
file.InputStream.Read(array, 0, array.Length);

AdjusterFile newFile = new AdjusterFile();

newFile.id = Guid.NewGuid();
newFile.adjusterID = adj.id;
newFile.type = "eo";
newFile.fileName = file.FileName;
newFile.fileContent = array;
newFile.fileContentType = file.ContentType;

db.AdjusterFiles.InsertOnSubmit(newFile);

コードが機能しない理由はGetBytes、MemoryStream で使用しているメソッドの MSDN ドキュメントからの次の引用にあります。

バッファーには、未使用の可能性がある割り当てられたバイトが含まれていることに注意してください。たとえば、文字列 "test" が MemoryStream オブジェクトに書き込まれた場合、GetBuffer から返されるバッファーの長さは 4 ではなく 256 で、252 バイトが未使用です。バッファー内のデータのみを取得するには、ToArray メソッドを使用します。ただし、ToArray はメモリ内にデータのコピーを作成します。

したがって、基本的に GetBytes メソッドでは、ストリームに書き込んだ正確なバイトを常に取得できるとは限りません。または、シナリオで正しく動作するメソッドを使用することもできますms.ToArray()が、正直なところ、この MemoryStream はまったく必要ありません。私の回答に示されているように、アップロードファイルの内容をバイト配列に直接読み取ることができる不要なスペースを割り当てているだけです。

重要な注意事項: バイト配列全体をメモリ内にロードすることで、特に大きなファイルで作業を開始した場合に、Web サーバーのメモリ消費量が急速に増加する可能性があることを理解していただければ幸いです。理想的な解決策は、ファイル システムにファイルを保存するか、MS SQL 2008 以降を使用している場合は新しい FILESTREAM タイプを利用することでした。

于 2013-07-10T14:38:58.550 に答える