ASP.NetコアでPDFを返すWep APIを作成しました。ここに私のコードがあります:
public HttpResponseMessage Get(int id)
{
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
var stream = new System.IO.FileStream(@"C:\Users\shoba_eswar\Documents\REquest.pdf", System.IO.FileMode.Open);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "NewTab";
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
return response;
}
ただし、JSON応答のみを返します。
{
"version":{
"major":1,
"minor":1,
"build":-1,
"revision":-1,
"majorRevision":-1,
"minorRevision":-1
},
"content":{
"headers":[
{
"key":"Content-Disposition",
"value":[
"attachment; filename=NewTab"
]
},
{
"key":"Content-Type",
"value":[
"application/pdf"
]
}
]
},
"statusCode":200,
"reasonPhrase":"OK",
"headers":[
],
"requestMessage":null,
"isSuccessStatusCode":true
}
ここで何か間違っていますか?
ASP.NET Core HTTPRequestMessageが奇妙なJSONメッセージを返す で説明されているように、ASP.NET CoreはHttpResponseMessage
(そのタイプにアクセスするためにどのパッケージをインストールしましたか?)を返すことをサポートしていません。
このため、シリアライザーは、サポートされていない他の応答タイプの場合と同様に、単にHttpResponseMessage
のすべてのパブリックプロパティを出力に書き込みます。
カスタム応答をサポートするには、IActionResult
-実装型を返す必要があります。 それらの多く があります。あなたの場合、 FileStreamResult
を調べます。
_public IActionResult Get(int id)
{
var stream = new FileStream(@"path\to\file", FileMode.Open);
return new FileStreamResult(stream, "application/pdf");
}
_
または、単純にストリームを処理する PhysicalFileResult
を使用します。
_public IActionResult Get(int id)
{
return new PhysicalFileResult(@"path\to\file", "application/pdf");
}
_
もちろん、これらすべては、Controller.File()
などのヘルパーメソッドを使用して単純化できます。
_public IActionResult Get(int id)
{
var stream = new FileStream(@"path\to\file", FileMode.Open);
return File(stream, "application/pdf", "FileDownloadName.ext");
}
_
これは、単純にFileContentResult
またはFileStreamResult
(このオーバーロードの場合は後者)の作成を抽象化します。
または、古いMVCまたはWeb APIアプリケーションを変換していて、すべてのコードを一度に変換したくない場合は、 WebApiCompatShim(NuGet) への参照を追加し、現在のコードを- ResponseMessageResult
:
_public IActionResult Get(int id)
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
var stream = ...
response.Content...
return new ResponseMessageResult(response);
}
_
return File(fileName, contentType, fileDownloadName)
を使用したくない場合、FileStreamResult
は、コンストラクターまたはプロパティを介したcontent-dispositionヘッダーの設定をサポートしません。
その場合、ファイルの結果を返す前に、その応答ヘッダーを自分で応答に追加する必要があります。
_var contentDisposition = new ContentDispositionHeaderValue("attachment");
contentDisposition.SetHttpFileName("foo.txt");
Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();
_
私の評判が十分に高くないため、CodeCasterによる回答にコメントできませんでした。しようとするとき
public IActionResult Get(int id)
{
using (var stream = new FileStream(@"path\to\file", FileMode.Open))
{
return File(stream, "application/pdf", "FileDownloadName.ext");
}
}
私たちは
ObjectDisposedException:破棄されたオブジェクトにアクセスできません。オブジェクト名:「閉じたファイルにアクセスできません。」。 System.IO.FileStream.BeginRead(byte []配列、intオフセット、int numBytes、AsyncCallbackコールバック、オブジェクト状態)
使用を削除しました
[HttpGet]
[Route("getImageFile")]
public IActionResult GetWorkbook()
{
var stream = new FileStream(@"pathToFile", FileMode.Open);
return File(stream, "image/png", "image.png");
}
そしてそれはうまくいきました。これは、IIS Expressで実行されているASP.NET Core 2.1です。
これをコメントとして投稿するほどの評判はありませんので、回答として投稿してください。 @CodeCasterの最初の3つのソリューションと@BernhardMaertlのソリューションは正しいです。
ただし、頻繁にファイルを操作しない人(私のような)の場合、このコードを実行するプロセス(APIなど)がファイルへの読み取り権限しか持たない場合は、作成時に3番目のパラメーターとして指定する必要がありますFileStream
、それ以外の場合、デフォルトの動作はファイルを読み取り/書き込み用に開くことで、書き込み権限がないため例外が発生します。
@CodeCasterの3番目のソリューションは次のようになります。
public IActionResult Get(int id)
{
var stream = new FileStream(@"path\to\file", FileMode.Open, FileAccess.Read);
return File(stream, "application/pdf", "FileDownloadName.ext");
}