【发布时间】:2019-03-13 07:55:58
【问题描述】:
我使用 .NET Core 创建并使用 HTTP 触发的 Azure 函数 (v2),希望我可以执行该函数,同时在请求正文中传递一些信息,然后让该函数在浏览器中返回/下载文件。不幸的是,我正在努力让它发挥作用。
下面是sn-p的代码
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, ILogger log)
{
string csv;
//Do some stuff to create a csv
byte[] filebytes = Encoding.UTF8.GetBytes(csv);
req.HttpContext.Response.Headers.Add("content-disposition", "attachment;filename=Export.csv");
req.HttpContext.Response.ContentType = "application/octet-stream";
return (ActionResult)new OkObjectResult(filebytes);
}
当我使用 Postman 发帖时,请求被接受,但响应为 406“不可接受”,并且日志状态中的输出
"Microsoft.AspNetCore.Mvc.Infrastructure.DefaultOutputFormatterSelector[1] 没有找到内容类型“application/octet-stream”的输出格式化程序来写入响应。”
我尝试了多种内容类型,包括 text/plain 和 text/csv,都对输出格式给出了相同的响应。
如果我删除或注释掉 ContentType,请求会处理并返回 200,但文件字节会在响应正文中返回,而不是在浏览器中下载。
【问题讨论】:
-
return new FileContentResult(fileBytes, "text/csv") { FileDownloadName = "Export.csv" };无需手动更改响应。 -
你的函数不应该直接返回文件。重点是卸载工作并在后台处理它。如果您的操作必须等待函数创建文件,您不妨改为在操作中完成所有操作,并放弃 Azure 函数的额外开销。假设它是在后台处理的,该函数应该以某种方式通过消息队列、SignalR 等通知您的应用程序已完成。然后,应用程序可以相应地通知客户端并推送下载或提供客户端可以下载的链接拿来。
-
是的,绝对是 Chris 所说的。从 Azure 函数返回文件也可能导致非常不可预测的成本,因为对于 Internet 连接速度快的用户,相同的函数可能运行 1 秒,而对于连接速度较慢的用户,则可能运行 30 秒。 Azure 函数应该主要是计算或后台任务,如果你返回文件,它们应该非常小(我会说在 1-2 kb 以下,比如一个小的 json 响应等),以避免在许多慢速连接时你的成本飙升。跨度>
-
处理文件时,您应该将结果文件存储到 azure 文件或 blob 存储中,并使该链接可供调用者使用,以便他们可以从那里直接访问它
-
感谢@AndyJ 完美运行!正如我在发布的答案中提到的那样,这是针对项目的一小部分,并且函数本身并不经常运行,返回非常少量的数据并在一两秒内运行,这就是我不同意的原因cmets中发布的其他解决方案。此外,我们将在现有的应用服务中托管它,因此与消费模型相关的成本不适用。感谢您的意见!
标签: c# asp.net-core .net-core azure-functions azure-functions-runtime