How to disable base64-encoded filenames in HttpClient/MultipartFormDataContent

。_饼干妹妹 提交于 2019-12-05 08:41:24

I just found the same limitation as StrezzOr, as the server that I was consuming didn't respect the filename* standard.

I converted the filename to a byte array of the UTF-8 representation, and the re-armed the bytes as chars of "simple" string (non UTF-8).

This code creates a content stream and add it to a multipart content:

        FileStream fs = File.OpenRead(_fullPath);
        StreamContent streamContent = new StreamContent(fs);
        streamContent.Headers.Add("Content-Type", "application/octet-stream");
        String headerValue = "form-data; name=\"Filedata\"; filename=\"" + _Filename + "\"";
        byte[] bytes = Encoding.UTF8.GetBytes(headerValue);
        headerValue="";
        foreach (byte b in bytes)
        {
            headerValue += (Char)b;
        }
        streamContent.Headers.Add("Content-Disposition", headerValue);
        multipart.Add(streamContent, "Filedata", _Filename);

This is working with spanish accents.

Hope this helps.

I recently found this issue and I use a workaround here:

At server side:

private static readonly Regex _regexEncodedFileName = new Regex(@"^=\?utf-8\?B\?([a-zA-Z0-9/+]+={0,2})\?=$");

private static string TryToGetOriginalFileName(string fileNameInput) {
    Match match = _regexEncodedFileName.Match(fileNameInput);
    if (match.Success && match.Groups.Count > 1) {
        string base64 = match.Groups[1].Value;
        try {
            byte[] data = Convert.FromBase64String(base64);
            return Encoding.UTF8.GetString(data);
        }
        catch (Exception) {
            //ignored
            return fileNameInput;
        }
    }
    return fileNameInput;
}

And then use this function like this:

string correctedFileName = TryToGetOriginalFileName(fileRequest.FileName);

It works.

I finally gave up and solved the task using HttpWebRequest instead of HttpClient. I had to build headers and content manually, but this allowed me to ignore the standards for sending non-ASCII filenames. I ended up cramming unencoded UTF-8 filenames into the filename header, which was the only way the server would accept my request.

In order to pass non-ascii characters in the Content-Disposition header filename attribute it is necessary to use the filename* attribute instead of the regular filename. See spec here.

To do this with HttpClient you can do the following,

   var streamcontent = new StreamContent(stream);
   streamcontent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
      FileNameStar = "99 2 LD 353 Temp Äüöß-1.txt" 
   };
   multipartContent.Add(streamcontent);

The header will then end up looking like this,

  Content-Disposition: attachment; filename*=utf-8''99%202%20LD%20353%20Temp%20%C3%84%C3%BC%C3%B6%C3%9F-1.txt
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!