HttpResponseMessage没有返回ByteArrayContent - ASP.NET Core

8

我有一些存储在数据库中的文件需要通过Web API返回。数据库调用可以正确地返回正确的字节数组(断点显示数组长度约为67000,这是正确的),但是当我调用Web API时,响应中从未返回该内容。我尝试使用MemoryStream和ByteArrayContent,但都没有给出我应该得到的结果。我尝试从Postman和我的MVC应用程序中调用,但都没有返回字节数组,只返回基本的响应信息和头部/成功等。

public HttpResponseMessage GetFile(int id)
{
    var fileToDownload = getFileFromDatabase(id);
    if (fileToDownload == null)
    {
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }
    var response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content = new ByteArrayContent(fileToDownload.FileData); //FileData is just a byte[] property in this class
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    return response;
}

我通常收到的响应(没有任何字节内容可找到):

{
  "version": {
    "major": 1,
    "minor": 1,
    "build": -1,
    "revision": -1,
    "majorRevision": -1,
    "minorRevision": -1
  },
  "content": {
    "headers": [
      {
        "key": "Content-Disposition",
        "value": [
          "attachment"
        ]
      },
      {
        "key": "Content-Type",
        "value": [
          "application/octet-stream"
        ]
      }
    ]
  },
  "statusCode": 200,
  "reasonPhrase": "OK",
  "headers": [],
  "requestMessage": null,
  "isSuccessStatusCode": true
}

也许我对如何处理这些数据存在误解,但我认为由于我明确添加了它,所以应该从Web API调用中返回它。

请确保您正在请求正确的操作方法。关于 GetFile 操作方法,它不会返回您描述的 JSON 结果。 - Win
Joe的评论解决了我的问题。我遗漏了文件上方的Route属性……调用本身是正确的,抱歉! - Robert McCoy
1个回答

13

我认为你应该使用FileContentResult,并且可能需要一个比"application/octet-stream"更具体的内容类型。

public IActionResult GetFile(int id)
{
    var fileToDownload = getFileFromDatabase(id);
    if (fileToDownload == null)
    {
        return NotFound();
    }

    return new FileContentResult(fileToDownload.FileData, "application/octet-stream");
}

哦,哇,是的,这绝对可以得到正确的结果。谢谢。我在这上面花了太长时间了,大多数Stackoverflow线程都试图强制使用HttpResponseMessage,我一直在寻找如何解决这个问题。如果我将拥有各种数据类型(图像、PDF、Office格式等),是否有更好的Content-Type?还是最好像八位字节流那样保持不变?我想我对不同的内容类型并不了解。 - Robert McCoy
我认为你应该在将文件放入数据库时捕获MIME类型,并将其作为fileToDownload的属性。您可以使用Static File包中的FileExtensionContentTypeProvider(https://github.com/aspnet/StaticFiles/blob/b49b46c5b63cf4db7285500470aed8ac0eea93db/src/Microsoft.AspNet.StaticFiles/FileExtensionContentTypeProvider.cs)来完成它,或者自己编写。 - Joe Audette
对于任何想知道 File() 和这个方法之间的区别的人来说,Controller 中的 File() 调用了这个方法。 - Chaim Eliyah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接