我正在开发一个asp.net mvc 4 Web应用程序。我正在使用.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()));
的问题,在这种情况下,其中一个参数包含&
,那么网址将具有以下格式&operation=AddAsset&assetName=&....
,因此它会假设我传递为空assetName参数不是值= &
??
修改
让我再次总结一下我的问题。我希望能够将我的URL中的以下3项内容传递给第三方API:
标准字符,例如A,B,a,b,1,2,3 ......
非{ASCII}字符,例如£
,¬
。
以及网址编码中使用的特殊字符,例如&
,+
。
现在我尝试了以下两种方法:
接近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
,它将作为%u00a3
而不是£
保存在第三方API中}。
方法B:
我用:
url.Query = Uri.EscapeUriString(HttpUtility.UrlDecode(query.ToString()));
而不是
url.Query = query.ToString();
现在我可以传递非{ASCII}字符,例如£
,因为它们将使用UTF8而不是ISO-8859-1正确编码。但是我无法传递&
之类的值,因为我的网址会被第三方API错误地读取..例如,如果我想传递assetName=&
,我的网址将如下所示:
&operation=Add&assetName=&
所以第三部分API将假设我传递空assetName
,而我正在尝试将其值传递为& ...
所以不确定如何传递非{ASCII}字符+ &
,+
等字符
答案 0 :(得分:9)
您可以改用System.Net.Http.FormUrlEncodedContent
。
这适用于名称/值配对和词典的词典,与NameValueCollection
不同,不会错误地#34;将£
等字符映射到无用的转义(%u00a3
,在您的情况下)。
相反,FormUrlEncodedContent
可以在其构造函数中使用字典。当你读出它的字符串时,它将正确地对字典值进行urlencoded。
它将正确且统一地处理您遇到问题的两种情况:
£
(超出urlencoding的字符值范围,需要编码为十六进制值才能传输)&
(正如您所说,它在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
。
答案 1 :(得分:3)
也许您可以尝试在Extension method
课程中使用NameValueCollection
。像这样:
using System.Collections.Specialized;
using System.Text;
using System.Web;
namespace Testing
{
public static class NameValueCollectionExtension
{
public static string ToUtf8UrlEncodedQuery(this NameValueCollection nv)
{
StringBuilder sb = new StringBuilder();
bool firstIteration = true;
foreach (var key in nv.AllKeys)
{
if (!firstIteration)
sb.Append("&");
sb.Append(HttpUtility.UrlEncode(key, Encoding.UTF8))
.Append("=")
.Append(HttpUtility.UrlEncode(nv[key], Encoding.UTF8));
firstIteration = false;
}
return sb.ToString();
}
}
}
然后,在您的代码中,您可以执行此操作:
url.Query = query.ToUtf8UrlEncodedQuery();
请务必为您放置using
课程的namespace
添加NameValueCollectionExtension
指令。
答案 2 :(得分:2)
这里的问题不是UriBuilder.Query,它是UriBuilder.ToString()。请阅读此处的文档:https://msdn.microsoft.com/en-us/library/system.uribuilder.tostring(v=vs.110).aspx。该属性定义为返回构建器的“显示字符串”,而不是有效编码的字符串。 Uri.ToString()有一个类似的问题,因为它没有执行正确的编码。
使用以下代码:url.Uri.AbsoluteUri
,它将始终是正确编码的字符串。你不应该在进入构建器的过程中进行任何编码(这是它的目的之一,毕竟,正确编码事物)。
答案 3 :(得分:2)
您需要使用:
System.Web.HttpUtility.UrlEncode(key)
将您的代码更改为:
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 = HttpUtility.UrlEncode(query.ToString());
string xml = client.DownloadString(url.ToString());
XmlDocument doc = new XmlDocument();
//code goes here ....
}
答案 4 :(得分:1)
如果没有任何帮助,那么只需在参数值
内手动转换那些有问题的字符& to %26
+ to %2B
? to %3F