Unicode in Content-Disposition header

后端 未结 7 1380
情歌与酒
情歌与酒 2020-12-03 17:46

I am using HttpContext object implemented in HttpHandler child to download a file, when I have non-ascii characters in file name it looks weird in IE whereas it looks fine i

相关标签:
7条回答
  • 2020-12-03 18:18

    HttpUtility.UrlPathEncode might be a better option. As URLEncode will replace spaces with '+' signs.

    0 讨论(0)
  • 2020-12-03 18:19

    For me this solved the problem:

    var result = new HttpResponseMessage(HttpStatusCode.OK)
    {
       Content = new ByteArrayContent(data)
    };
    
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileNameStar = "foo-ä-€.html"
    };
    

    When i look ad the repsonse in fiddler i can see the filename has automaticcaly been encoded using UTF-8:

    Fiddler response example with encoded Content-Disposition filename using UTF-8

    If we look at the value of the Content-Disposition header we can see it will be the same as @Johannes Geyer his answer. The only difference is that we didn't have to do the encoding ourselfs, the ContentDispositionHeaderValue class takes care of that.

    I used the Testcases for the Content-Disposition header on: http://greenbytes.de/tech/tc2231/ as mentioned by Julian Reschke. Information about the ContentDispositionHeaderValue class can be found on MSDN.

    0 讨论(0)
  • 2020-12-03 18:27

    I`m using Uri.EscapeUriString for converts all characters to their hexadecimal representation, and string.Normalize for Unicode normalization form C. (tested in ASP.NET MVC5 framework 4.5)

        var contentDispositionHeader = new System.Net.Mime.ContentDisposition
        {
            Inline = false,
            FileName = Uri.EscapeUriString(Path.GetFileName(pathFile)).Normalize()
        };
        Response.Headers.Add("Content-Disposition", contentDispositionHeader.ToString());
        string mimeType = MimeMapping.GetMimeMapping(Server.MapPath(pathFile));
        return File(file, mimeType);
    
    0 讨论(0)
  • 2020-12-03 18:33

    For Asp.Net Core (version 2 as of this post) UrlPathEncode is deprecated, here's how to achieve the desired result:

    System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
    {
       FileName = Uri.EscapeUriString(fileName),
       Inline = true  // false = prompt the user for downloading;  true = browser to try to show the file inline
    };
    
    Response.Headers.Add("Content-Disposition", cd.ToString());
    
    0 讨论(0)
  • 2020-12-03 18:34

    I had similar problem. You have to use HttpUtility.UrlEncode or Server.UrlEncode to encode filename. Also I remember firefox didn't need it. Moreoverit ruined filename when it's url-encoded. My code:

    // IE needs url encoding, FF doesn't support it, Google Chrome doesn't care
    if (Request.Browser.IsBrowser ("IE"))
    {
        fileName = Server.UrlEncode(fileName);
    }
    
    Response.Clear ();
    Response.AddHeader ("content-disposition", String.Format ("attachment;filename=\"{0}\"", fileName));
    Response.AddHeader ("Content-Length", data.Length.ToString (CultureInfo.InvariantCulture));
    Response.ContentType = mimeType;
    Response.BinaryWrite(data);
    

    Edit

    I have read specification more carefully. First of all RFC2183 states that:

    Current [RFC 2045] grammar restricts parameter values (and hence Content-Disposition filenames) to US-ASCII.

    But then I found references that [RFC 2045] is absolete and one must reference RFC 2231, which states:

    Asterisks ("*") are reused to provide the indicator that language and character set information is present and encoding is being used. A single quote ("'") is used to delimit the character set and language information at the beginning of the parameter value. Percent signs ("%") are used as the encoding flag, which agrees with RFC 2047.

    Which means that you can use UrlEncode for non-ascii symbols, as long as you include the encoding as stated in the rfc. Here is an example:

    string.Format("attachment; filename=\"{0}\"; filename*=UTF-8''{0}", Server.UrlEncode(fileName, Encoding.UTF8));
    

    Note that filename is included in addition to filename* for backwards compatibility. You can also choose another encoding and modify the parameter accordingly, but UTF-8 covers everything.

    0 讨论(0)
  • 2020-12-03 18:39

    For me this solution is working on all major browsers:

    Response.AppendHeader("Content-Disposition", string.Format("attachment; filename*=UTF-8''{0}", HttpUtility.UrlPathEncode(fileName).Replace(",", "%2C"));
    var mime = MimeMapping.GetMimeMapping(fileName);
    return File(fileName, mime);
    

    Using ASP.NET MVC 3.

    The Replace is necessary, because Chrome doesn't like Comma (,) in parameter values: http://www.gangarasa.com/lets-Do-GoodCode/tag/err_response_headers_multiple_content_disposition/

    0 讨论(0)
提交回复
热议问题