How to set downloading file name in ASP.NET Web API

C#asp.net Web-Api

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

You need to set the Content-Disposition header on the HttpResponseMessage:

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

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

I think that this might be helpful to you.

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

Solution 5 - C#

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;

Solution 6 - C#

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

Solution 7 - C#

This should do:

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

Solution 8 - C#

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

Solution 9 - C#

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTae-Sung ShinView Question on Stackoverflow
Solution 1 - C#Darin DimitrovView Answer on Stackoverflow
Solution 2 - C#AndyCView Answer on Stackoverflow
Solution 3 - C#sorenhkView Answer on Stackoverflow
Solution 4 - C#JarekView Answer on Stackoverflow
Solution 5 - C#Carl RaymondView Answer on Stackoverflow
Solution 6 - C#PeterView Answer on Stackoverflow
Solution 7 - C#tucazView Answer on Stackoverflow
Solution 8 - C#Chandan Y SView Answer on Stackoverflow
Solution 9 - C#AserewareView Answer on Stackoverflow