FormUrlEncode returns 编码 º(男性序数指示符)的意外结果
FormUrlEncode returns unexpected result encoding the º(masculine ordinal indicator)
我有一个程序与外部 http 服务器通信以请求第一个、第二个等值...(1º
、2º
、3º
、4º
,...)
我在 c# 中遇到 º
字符的问题。
下面是一些示例代码:
var testdata=new Dictionary<string,string>{
{"val","º"},
{"val1","\xBA"},
{"val2","\u00BA"},
};
var content = new FormUrlEncodedContent(testdata);
var cont = content.ReadAsStringAsync().GetAwaiter().GetResult();
结果是:
val=%C2%BA&val1=%C2%BA&val2=%C2%BA
我用 curl 和 firefox 控制台测试与服务器的通信
结果应该是:
val=%BA&val1=%BA&val2=%BA
C# dosent 中的额外 %C2
以某种方式与服务器一起工作。
如何正确修复或转义 º
?
°
的正确 unicode 字符是 \u00B0
。更多信息,您可以找到 here 如何在 C# 中使用 unicode。
可以找到所有 unicode 字符 here。
此问题与 FormUrlEncodedContent
使用的默认编码有关,即 UTF-8
而您的服务器期望 ISO-8859-1
。
这是克服它的解决方法,但您需要(不幸的是)将 System.Web
添加到您的项目中:
// This is an implementation of FormUrlEncodedContent with `ISO-8859-1`
public class FormIso8859Encoder : ByteArrayContent
{
public FormIso8859Encoder(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
: base(FormDataToByteArray(nameValueCollection))
{
Headers.Add("Content-Type", "application/x-www-form-urlencoded");
}
private static byte[] FormDataToByteArray(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
{
StringBuilder sb = new StringBuilder();
foreach (var nameValue in nameValueCollection)
{
if (sb.Length > 0)
sb.Append('&');
sb.Append(nameValue.Key);
sb.Append('=');
// Here is the major change
sb.Append(HttpUtility.UrlEncode(nameValue.Value, Encoding.GetEncoding("iso-8859-1") ));
}
return Encoding.Default.GetBytes(sb.ToString());
}
}
然后
var testdata=new Dictionary<string,string>{
{"val","º"},
{"val1","\xBA"},
{"val2","\u00BA"},
};
var content = new FormIso8859Encoder(testdata);
var cont = content.ReadAsStringAsync().GetAwaiter().GetResult();
这提供了以下输出:
val=%BA&val1=%BA&val2=%BA
我有一个程序与外部 http 服务器通信以请求第一个、第二个等值...(1º
、2º
、3º
、4º
,...)
我在 c# 中遇到 º
字符的问题。
下面是一些示例代码:
var testdata=new Dictionary<string,string>{
{"val","º"},
{"val1","\xBA"},
{"val2","\u00BA"},
};
var content = new FormUrlEncodedContent(testdata);
var cont = content.ReadAsStringAsync().GetAwaiter().GetResult();
结果是:
val=%C2%BA&val1=%C2%BA&val2=%C2%BA
我用 curl 和 firefox 控制台测试与服务器的通信 结果应该是:
val=%BA&val1=%BA&val2=%BA
C# dosent 中的额外 %C2
以某种方式与服务器一起工作。
如何正确修复或转义 º
?
°
的正确 unicode 字符是 \u00B0
。更多信息,您可以找到 here 如何在 C# 中使用 unicode。
可以找到所有 unicode 字符 here。
此问题与 FormUrlEncodedContent
使用的默认编码有关,即 UTF-8
而您的服务器期望 ISO-8859-1
。
这是克服它的解决方法,但您需要(不幸的是)将 System.Web
添加到您的项目中:
// This is an implementation of FormUrlEncodedContent with `ISO-8859-1`
public class FormIso8859Encoder : ByteArrayContent
{
public FormIso8859Encoder(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
: base(FormDataToByteArray(nameValueCollection))
{
Headers.Add("Content-Type", "application/x-www-form-urlencoded");
}
private static byte[] FormDataToByteArray(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
{
StringBuilder sb = new StringBuilder();
foreach (var nameValue in nameValueCollection)
{
if (sb.Length > 0)
sb.Append('&');
sb.Append(nameValue.Key);
sb.Append('=');
// Here is the major change
sb.Append(HttpUtility.UrlEncode(nameValue.Value, Encoding.GetEncoding("iso-8859-1") ));
}
return Encoding.Default.GetBytes(sb.ToString());
}
}
然后
var testdata=new Dictionary<string,string>{
{"val","º"},
{"val1","\xBA"},
{"val2","\u00BA"},
};
var content = new FormIso8859Encoder(testdata);
var cont = content.ReadAsStringAsync().GetAwaiter().GetResult();
这提供了以下输出:
val=%BA&val1=%BA&val2=%BA