正如中所解释的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
or 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
不支持从构造函数或通过属性设置内容处置标头。
在这种情况下,您必须在返回文件结果之前自行将该响应标头添加到响应中:
var contentDisposition = new ContentDispositionHeaderValue("attachment");
contentDisposition.SetHttpFileName("foo.txt");
Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();