我正在使用HttpClient
将MultipartFormDataContent
POST到Java Web应用程序。我正在使用StringContents
方法使用StreamContent
上传多个MultipartFormDataContent.Add(HttpContent content, String name, String fileName)
和一个我添加为HttpClient.PostAsync(String, HttpContent)
的文件。
这很好用,除非我提供包含德语变音符号的 fileName (我还没有测试过其他非ASCII字符)。在这种情况下, fileName 正在进行base64编码。名为 99 2 LD 353TempÄüöß-1.txt
的文件的结果看起来像这样:
__utf-8_B_VGVtcCDvv73vv73vv73vv71cOTkgMiBMRCAzNTMgVGVtcCDvv73vv73vv73vv70tMS50eHQ___
Java服务器在其UI中显示此编码文件名,这会使用户感到困惑。我无法进行任何服务器端更改。
如何禁用此行为?任何帮助都将受到高度赞赏。
提前致谢!
答案 0 :(得分:8)
我刚刚发现了与StrezzOr相同的限制,因为我所使用的服务器并不尊重文件名*标准。
我将文件名转换为UTF-8表示的字节数组,并将字节重新设置为"简单"的字符。 string(非UTF-8)。
此代码创建内容流并将其添加到多部分内容:
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);
这适用于西班牙语口音。
希望这有帮助。
答案 1 :(得分:1)
我终于放弃并使用HttpWebRequest
而不是HttpClient
解决了任务。我必须手动构建标题和内容,但这使我忽略了发送非ASCII文件名的标准。我最终将未编码的UTF-8文件名塞进filename
标题中,这是服务器接受我的请求的唯一方式。
答案 2 :(得分:1)
我最近发现了这个问题,我在这里使用了一种解决方法:
在服务器端:
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;
}
然后像这样使用这个函数:
string correctedFileName = TryToGetOriginalFileName(fileRequest.FileName);
有效。
答案 3 :(得分:0)
为了在Content-Disposition标头文件名属性中传递非ascii字符,必须使用filename*
属性而不是常规filename
。请参阅规范here。
要使用HttpClient执行此操作,您可以执行以下操作,
var streamcontent = new StreamContent(stream);
streamcontent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {
FileNameStar = "99 2 LD 353 Temp Äüöß-1.txt"
};
multipartContent.Add(streamcontent);
标题最终会看起来像这样,
Content-Disposition: attachment; filename*=utf-8''99%202%20LD%20353%20Temp%20%C3%84%C3%BC%C3%B6%C3%9F-1.txt