【问题标题】:How to return file from ASP.net 5 web api如何从 ASP.net 5 web api 返回文件
【发布时间】:2016-04-23 12:37:55
【问题描述】:

在 asp.net 5 中创建了 wep api。我正在尝试返回 Post 请求的文件响应。但不是文件,而是响应看起来像 `

{
  "version": {
    "major": 1,
    "minor": 1,
    "build": -1,
    "revision": -1,
    "majorRevision": -1,
    "minorRevision": -1
  },
  "content": {
    "headers": [
      {
        "key": "Content-Disposition",
        "value": [
          "attachment; filename=test.pdf"
        ]
      },
      {
        "key": "Content-Type",
        "value": [
          "application/pdf"
        ]
      }
    ]
  },
  "statusCode": 200,
  "reasonPhrase": "OK",
  "headers": [],
  "requestMessage": null,
  "isSuccessStatusCode": true
}`

代码:

    public HttpResponseMessage Post([FromBody]DocumentViewModel vm)
    {
        try
        {
            if (ModelState.IsValid)
            {

                var Document = _repository.GetDocumentByGuid(vm.DocumentGuid, User.Identity.Name);
                var Params = Helper.ClientInputToRealValues(vm.Parameters, Document.DataFields);
                var file = Helper.GeneratePdf(Helper.InsertValues(Params, Document.Content));                 

                var result = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new ByteArrayContent(System.IO.File.ReadAllBytes(file))
                };
                result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                {
                    FileName = "test.pdf"
                };
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
                return result;

            }

        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return null;
        }
        Response.StatusCode = (int)HttpStatusCode.BadRequest;
        return null;

    }

如何将真实文件作为响应而不是 JSON 返回?我使用 Postman 作为测试客户端。

【问题讨论】:

标签: asp.net-web-api asp.net-core postman


【解决方案1】:

设置HttpContext.Response.ContentType = "application/pdf" 有帮助吗?

这应该符合您的需求:

public FileResult TestDownload()
    {
        HttpContext.Response.ContentType = "application/pdf";
        FileContentResult result = new FileContentResult(System.IO.File.ReadAllBytes("YOUR PATH TO PDF"), "application/pdf")
        {
            FileDownloadName = "test.pdf"
        };

        return result;                                
    }

【讨论】:

  • "headers": [], 现在有填充内容吗?正如我从您最初的帖子中看到的那样,它是空的。您使用的是什么版本的 asp.net 5,它是完整的 .net 还是 coreclr?
  • 不,它仍然是空的。
  • 完整 - dnx451,构建 rc1-final
  • 如果我像这样手动将标头添加到 HttpResponseMessage: result.Headers.Add("Content-Type", "application/pdf");它抛出:“错误的标头名称。确保请求标头与 HttpRequestMessage 一起使用,响应标头与 HttpResponseMessage 一起使用,内容标头与 HttpContent 对象一起使用。”
【解决方案2】:

使用 IActionResult 而不是 HttpResponseMessage。并返回 FileStreamResult,并让它工作。

遇到了一个新问题,该文件不是我使用来自服务器的流打开的文件。但会为此提出一个新问题。

继续:Return file from ASP.NET 5 Web API

谢谢

【讨论】:

    【解决方案3】:

    这是“低级”HTTP 方法,应该适用于 ASP.NET WebAPI 或 ASP.NET MVC。

    [HttpGet]
    public HttpResponseMessage Download()
    {
      var fs = new FileStream(myfileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, 32768, true);
      var response = new HttpResponseMessage {
        Content = new StreamContent(fs);
      }
      response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
      response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
      return response;
    }
    

    【讨论】:

    • 不会fs.Dispose() 在 WebAPI 有机会使用文件流之前关闭文件吗?如果不是,那么Dispose() 在这种情况下如何工作?
    • 回答我上面的问题:您不需要(也可能不应该)在传递给StreamContent 的流上调用Dispose。我会编辑你的答案。见stackoverflow.com/a/38788127/2279059
    • 它仍然不是 WebAPI,因为 this.Request.CreateResponse 不存在于 WebAPI 控制器中。
    猜你喜欢
    • 2016-04-23
    • 2016-03-16
    • 2018-07-17
    • 1970-01-01
    • 2016-12-17
    • 2021-09-24
    • 2019-01-17
    • 2016-07-11
    • 2015-01-05
    相关资源
    最近更新 更多