【问题标题】:How to set downloading file name in ASP.NET Web API如何在 ASP.NET Web API 中设置下载文件名
【发布时间】:2012-08-22 03:24:57
【问题描述】:

在我的 ApiController 类中,我有以下方法来下载服务器创建的文件。

public HttpResponseMessage Get(int id)
{
    try
    {
        string dir = HttpContext.Current.Server.MapPath("~"); //location of the template file
        Stream file = new MemoryStream();
        Stream result = _service.GetMyForm(id, dir, file);
        if (result == null)
        {
            return Request.CreateResponse(HttpStatusCode.NotFound);
        }
        result.Position = 0;
        HttpResponseMessage response = new HttpResponseMessage();
        response.StatusCode = HttpStatusCode.OK;
        response.Content = new StreamContent(result);
        return response;
    }
    catch (IOException)
    {
        return Request.CreateResponse(HttpStatusCode.InternalServerError);
    }
}

除了默认的下载文件名是它的 id 之外,一切都运行良好,因此用户可能必须每次在另存为对话框中键入他/她自己的文件名。有没有办法在上面的代码中设置一个默认的文件名?

【问题讨论】:

  • 你能分享一下你用来调用这个方法的代码吗?
  • @Yasser - 这是一个 Web API 控制器方法 - 它可能通过进入 IIS 并解析它们并查找路由和调用该方法的 Web API 的 HTTP 请求被调用(当然,它也是由测试调用)。
  • GetMyForm() 内部发生了什么?将文件转换为字节流?
  • @MSIslam 之类的。该函数从用户表单中获取信息并在转换为结果流之前创建一个文件。

标签: c# asp.net-web-api


【解决方案1】:

考虑到前面的答案,需要注意全球化字符。

假设文件名是:“Esdrújula prenda ñame - güena.jpg

原始结果下载:“Esdrújula prenda ñame - güena.jpg”[丑陋]

HtmlEncode结果下载:“Esdr&_250;jula prenda &_241;ame - g&_252;ena.jpg”[丑]

UrlEncode 结果下载:“Esdrújula+prenda+ñame+-+güena.jpg”[OK]

然后,您需要几乎总是在文件名上使用 UrlEncode。 此外,如果您将 content-disposition 标头设置为直接字符串,则需要确保用引号括起来以避免浏览器兼容性问题。

Response.AddHeader("Content-Disposition", $"attachment; filename=\"{HttpUtility.UrlEncode(YourFilename)}\"");

或在课堂帮助下:

var cd = new ContentDisposition("attachment") { FileName = HttpUtility.UrlEncode(resultFileName) };
Response.AddHeader("Content-Disposition", cd.ToString());

System.Net.Mime.ContentDisposition 类负责处理引号。

【讨论】:

    【解决方案2】:

    注意:最后一行是强制性的。

    如果我们没有指定 Access-Control-Expose-Headers,我们将不会在 UI 中获取 File Name。

    FileInfo file = new FileInfo(FILEPATH);
    
    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = file.Name
    };
    response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
    

    【讨论】:

      【解决方案3】:

      如果您使用的是 ASP.NET Core MVC,上面的答案会稍有改变...

      在我的操作方法(返回 async Task<JsonResult>)中,我添加了这一行(返回语句之前的任何位置):

      Response.Headers.Add("Content-Disposition", $"attachment; filename={myFileName}");
      

      【讨论】:

      • 不包括转义。如果文件名包含 ;还是其他有特殊含义的东西?
      【解决方案4】:

      应该这样做:

      Response.AddHeader("Content-Disposition", "attachment;filename="+ YourFilename)
      

      【讨论】:

      • 不包括转义。如果文件名包含; 或其他具有特殊含义的东西怎么办?
      【解决方案5】:

      如果你想确保文件名被正确编码但又避免 WebApi HttpResponseMessage 你可以使用以下:

      Response.AddHeader("Content-Disposition", new System.Net.Mime.ContentDisposition("attachment") { FileName = "foo.txt" }.ToString());
      

      您可以使用 ContentDisposition 或 ContentDispositionHeaderValue。在任一实例上调用 ToString 将为您完成文件名的编码。

      【讨论】:

        【解决方案6】:

        编辑: 正如评论中提到的,我的回答没有考虑像; 这样需要转义的字符。如果您的文件名可能包含分号,您应该使用 Darin 提供的公认答案。

        添加一个Response.AddHeader来设置文件名

        Response.AddHeader("Content-Disposition", "attachment; filename=*FILE_NAME*");
        

        只需将 FILE_NAME 更改为文件名即可。

        【讨论】:

        • 事实证明,这对我解决与提问者类似的问题很有帮助。就我而言,我还发现将“附件”更改为“内联”很有用,这样 IE8 就会让我选择始终打开相关文件类型。
        • 不包括转义。如果文件名中包含; 或其他具有特殊含义的内容怎么办?
        • Sam,3 年前我写这个答案的时候,我没有意识到我的答案需要处理转义。感谢您向我指出这一点,我对我的答案进行了编辑,解释我的答案不能解释转义。但保持我的回答不变,因为它似乎对人们有所帮助。
        【解决方案7】:

        您需要在HttpResponseMessage 上设置Content-Disposition 标头:

        HttpResponseMessage response = new HttpResponseMessage();
        response.StatusCode = HttpStatusCode.OK;
        response.Content = new StreamContent(result);
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "foo.txt"
        };
        

        【讨论】:

        • 对于任何对“附件”处置类型感兴趣的人,处置类型的完整列表位于 iana.org/assignments/cont-disp/cont-disp.xhtml
        • 您对downloading a file here. 有另一个答案您使用System.Net.Mime.ContentDisposition 还是ContentDispositionHeaderValue 是否重要?一个比另一个更流行和更受欢迎吗?
        • @Luminous 一个答案是ActionResult,一个答案是HttpResponseMessage
        • @Luminous “这有关系吗”和“一个比另一个更流行、更受欢迎吗?”不,也不。一种用于 MVC ActionResults,一种用于 WebApi HttpResponseMessages。
        • 根据@sfuqua 提供的链接,我将它与“内联”而不是“附件”一起使用,效果很好。例如浏览器中显示的 PDF 和下载的 Word 文档等
        【解决方案8】:

        您需要将 content-disposition 标头添加到响应中:

         response.StatusCode = HttpStatusCode.OK;
         response.Content = new StreamContent(result);
         response.AppendHeader("content-disposition", "attachment; filename=" + fileName);
         return response;
        

        【讨论】:

        • 不包括转义。如果文件名包含; 或其他具有特殊含义的内容怎么办?
        【解决方案9】:

        我认为这可能对您有所帮助。

        Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName)
        

        【讨论】:

        • 不包括转义。如果文件名包含; 或其他具有特殊含义的东西怎么办?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-12
        • 2012-10-10
        • 1970-01-01
        • 1970-01-01
        • 2016-11-15
        相关资源
        最近更新 更多