[c#] How to set downloading file name in ASP.NET Web API

In my ApiController class, I have following method to download a file created by server.

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);
    }
}

Everything is working perfect except that default downloading file name is its id so user might have to type his/her own file name at save as dialog each time. Is there any way to set a default file name in the code above?

This question is related to c# asp.net-web-api

The answer is


I think that this might be helpful to you.

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

If you want to ensure that the file name is properly encoded but also avoid the WebApi HttpResponseMessage you can use the following:

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

You may use either ContentDisposition or ContentDispositionHeaderValue. Calling ToString on an instance of either will do the encoding of file names for you.


You need to add the content-disposition header to the response:

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

EDIT: As mentioned in a comment, My answer doesn't account for characters that need to be escaped like a ;. You should use the accepted answer Darin made if your file name could contain a semi-colon.

Add a Response.AddHeader to set the file name

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

Just change FILE_NAME to the name of the file.


Note: The last line is mandatory.

If we didn't specify Access-Control-Expose-Headers, we will not get File Name in 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");

This should do:

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

If you are using ASP.NET Core MVC, the answers above are ever so slightly altered...

In my action method (which returns async Task<JsonResult>) I add the line (anywhere before the return statement):

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

Considering the previous answers, it is necessary to be careful with globalized characters.

Suppose the name of the file is: "Esdrújula prenda ñame - güena.jpg"

Raw result to download: "Esdrújula prenda ñame - güena.jpg" [Ugly]

HtmlEncode result to download: "Esdr&_250;jula prenda &_241;ame - g&_252;ena.jpg" [Ugly]

UrlEncode result to download: "Esdrújula+prenda+ñame+-+güena.jpg" [OK]

Then, you need almost always to use the UrlEncode over the file name. Moreover, if you set the content-disposition header as direct string, then you need to ensure surround with quotes to avoid browser compatibility issues.

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

or with class aid:

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

The System.Net.Mime.ContentDisposition class takes care of quotes.