我正在开发一个 asp.net mvc 4 网络应用程序。我正在使用.net 4.5。现在我有以下 WebClient()
类:
using (var client = new WebClient())
{
var query = HttpUtility.ParseQueryString(string.Empty);
query["model"] = Model;
//code goes here for other parameters....
string apiurl = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiURL"];
var url = new UriBuilder(apiurl);
url.Query = query.ToString();
string xml = client.DownloadString(url.ToString());
XmlDocument doc = new XmlDocument();
//code goes here ....
}
现在我注意到一个问题,当其中一个参数包含非 ASCII 租船人时,例如 £
、¬
等....
现在最终查询将包含错误编码的任何非 ASCII 字符(如 £
)(如 %u00a3
)。我读到了这个问题,似乎我可以替换 :-
url.Query = query.ToString();
与
url.Query = ri.EscapeUriString(HttpUtility.UrlDecode(query.ToString()));
现在使用后一种方法会将 £
编码为 %C2%A3
,这是正确的编码值。
但我面临的问题是 url.Query = Uri.EscapeUriString(HttpUtility.UrlDecode(query.ToString()));
在这种情况下,其中一个参数包含 &
然后 url 将具有以下格式 &operation=AddAsset&assetName=&....
所以它会假设我传递的是空 assetName 参数而不是值 =&
? ?
编辑
让我再总结一下我的问题。我希望能够将我的 URL 中的以下 3 项内容传递给第三方 API:
标准字符,例如 A,B ,a ,b ,1, 2, 3 ...
非 ASCII 字符,例如
£
、¬
。还有在 url 编码中使用的特殊字符,例如
&
,+
。
现在我尝试了以下两种方法:
方法 A:
using (var client = new WebClient())
{
var query = HttpUtility.ParseQueryString(string.Empty);
query["model"] = Model;
//code goes here for other parameters....
string apiurl = System.Web.Configuration.WebConfigurationManager.AppSettings["ApiURL"];
var url = new UriBuilder(apiurl);
url.Query = query.ToString();
string xml = client.DownloadString(url.ToString());
XmlDocument doc = new XmlDocument();
//code goes here ....
}
在这种方法中,我可以传递诸如 &
、+
之类的值,因为它们将被 url 编码,但是如果我想传递非 ASCII 字符,它们将使用 ISO-8859-1 进行编码 ... 所以如果我有 £
值,我上面的代码将编码为 %u00a3
并将保存在第 3 方中API 作为 %u00a3
而不是 £
。
方法 B:
我用:
url.Query = Uri.EscapeUriString(HttpUtility.UrlDecode(query.ToString()));
代替
url.Query = query.ToString();
现在我可以传递非 ASCII 字符,例如 £
,因为它们将使用 UTF8 而不是 ISO-8859-1 进行正确编码。但我无法传递诸如 &
之类的值,因为我的 url 会被第 3 方 API 错误读取。例如,如果我想传递 assetName=&
我的 url 将看起来如下:
&operation=Add&assetName=&
所以第三部分 API 将假设我正在传递空的 assetName
,而我试图将它的值传递为 &...
所以不确定如何传递非 ASCII 字符 + 字符,例如 &
、+
????
最佳答案
您可以改用 System.Net.Http.FormUrlEncodedContent
。
与 NameValueCollection
不同,这与用于名称/值配对的字典一起使用,字典不会“错误地”将 £
等字符映射到无用的转义字符(%u00a3
,在您的情况下)。
相反,FormUrlEncodedContent
可以在其构造函数中使用字典。当您从中读取字符串时,它将正确地对字典值进行 urlencoded。
它将正确且统一地处理您遇到的两种情况:
£
(超出urlencoding的字符取值范围,需要编码成16进制值才能传输)&
(正如您所说,它在 url 中作为参数分隔符具有意义,因此值不能包含它——因此它也必须被编码)。
这是一个代码示例,它显示了您提到的各种示例项目(由 item1、item2 和 item3 表示)现在最终正确地进行了 urlencoded:
String item1 = "£";
String item2 = "&";
String item3 = "xyz";
Dictionary<string,string> queryDictionary = new Dictionary<string, string>()
{
{"item1", item1},
{"item2", item2},
{"item3", item3}
};
var queryString = new System.Net.Http.FormUrlEncodedContent(queryDictionary)
.ReadAsStringAsync().Result;
queryString
将包含 item1=%C2%A3&item2=%26&item3=xyz
。
关于c# - UriBuilder().Query 将错误地编码非 ASCII 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38877544/