【问题标题】:How to download file using IHttpClientFactory in .Net Core 2.2?如何在 .Net Core 2.2 中使用 IHttpClientFactory 下载文件?
【发布时间】:2019-04-17 02:21:29
【问题描述】:

在我的网络应用程序 (.net Core 2.2) 中,我想添加下载 PDF 文件的功能。

当用户点击“下载”时 - POST 被发送到 WebAPI,服务器通过硬编码的 URL(用户不可见)向不同的服务器请求 PDF 文件,并将文件传递给用户。

我尝试使用IHttpClientFactory

启动:

services.AddHttpClient("demo", c =>
{
    c.BaseAddress = new Uri("http://www.africau.edu/");
    c.DefaultRequestHeaders.Add("Accept", "application/pdf");
});

返回PDF文件的方法:

public async Task<FileStreamResult> GetPdfFile()
{    
    var client = _httpClientFactory.CreateClient("demo");
    var uri = new UriBuilder(client.BaseAddress + "images/default/sample.pdf").Uri;
    var stream = await client.GetStreamAsync(uri);

    return new FileStreamResult(stream, new MediaTypeHeaderValue("application/pdf"));
}

不幸的是,它返回文件download.json{"fileStream":{"needsDrain":true,"canRead":true,"canWrite":false,"canSeek":false p>


@EDIT

似乎是因为我的 Controller 中有 Task&lt;IActionResult&gt; 而不是 Task&lt;FileStreamResult&gt; 但如果我更愿意返回 ActionResult 怎么办?

public async Task<IActionResult> GetPdf()
{
    var result = await _service.GetPdfFile();
    return Ok(result);
}

【问题讨论】:

  • 这个问题似乎缺少一些信息。什么在消耗“GetPdfFile”端点?您在哪里看到正在下载的“download.json”文件;是当您从浏览器点击“GetPdfFile”端点时,还是浏览器和“GetPdfFile”之间还有另一层?
  • UI -> Controll WebApi -> GetPdfFile 方法。 download.json 返回给用户。谁点击了 UI 上的“下载”。所以似乎API返回了一些文件。
  • 您的“Control WebApi”似乎正在将流序列化为 JSON,而不是返回流的内容。那层的action方法的内容是什么?
  • @Arcanox 我编辑了帖子。此方法具有返回类型:Task,并且只有:return OK(result),这是此方法的结果。
  • 您能否更新您的问题以显示完整的方法?这样我就可以发布相关的答案。使用Ok(result) 将使用默认序列化程序序列化result,并将序列化内容作为200 OK 响应返回,这将解释您所看到的行为。

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


【解决方案1】:

在您的GetPdf 方法中,您将FileStreamResult 传递给Ok() 方法。这将使用默认序列化程序序列化 FileStreamResult 并将其发送到客户端,因此您会看到 JSON。

通常,您的服务层不应返回 MVC WhateverResult 对象,而是旨在表示正在检索的实际数据的对象 - 在您的情况下,这将是一个 PDF 文件。解决您的特定情况的最简单方法可能是执行以下操作:

  • GetPdfFile 更改为返回Task&lt;FileStream&gt; 而不是Task&lt;FileStreamResult&gt;
    • 记得把它的return语句改成return stream;
  • GetPdf的return语句改为return File(result, "application/pdf");

这将允许您的服务层将 PDF 文件作为流返回,然后让您的 GetPdf 端点将该流作为具有 application/pdf 文件类型的文件返回。

【讨论】:

  • result 中的return File(result, "application/pdf"); 是什么?
  • @DiPix 它将是来自GetPdfFile 的返回值,在进行我建议的更改后,它应该是FileStream。您可以随意命名变量。
猜你喜欢
  • 2019-03-13
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-15
  • 2021-03-01
  • 1970-01-01
  • 2019-02-10
相关资源
最近更新 更多