149

在我的 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 之外,一切都运行良好,因此用户可能每次都必须在另存为对话框中键入他/她自己的文件名。有没有办法在上面的代码中设置默认文件名?

4

9 回答 9

305

您需要在以下位置设置Content-Disposition标题HttpResponseMessage

HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(result);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = "foo.txt"
};
于 2012-08-27T16:06:10.003 回答
28

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

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

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

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

于 2012-08-27T16:03:30.590 回答
9

如果要确保文件名正确编码但又要避免使用 WebApi HttpResponseMessage,则可以使用以下命令:

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

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

于 2016-09-12T07:18:37.027 回答
6

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

Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName)
于 2012-08-27T16:03:40.483 回答
3

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

 response.StatusCode = HttpStatusCode.OK;
 response.Content = new StreamContent(result);
 response.AppendHeader("content-disposition", "attachment; filename=" + fileName);
 return response;
于 2012-08-27T16:04:27.410 回答
3

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

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

Response.Headers.Add("Content-Disposition", $"attachment; filename={myFileName}");
于 2017-07-17T15:20:14.233 回答
2

这应该这样做:

Response.AddHeader("Content-Disposition", "attachment;filename="+ YourFilename)
于 2012-08-27T16:04:41.703 回答
0

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

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

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");
于 2019-03-28T06:17:19.483 回答
0

考虑到以前的答案,有必要小心全球化的字符。

假设文件名是:“ 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类负责引号。

于 2019-10-31T18:44:28.603 回答