c# - UriBuilder().Query 将错误地编码非 ASCII 字符

标签 c# asp.net .net asp.net-mvc http

我正在开发一个 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:

  1. 标准字符,例如 A,B ,a ,b ,1, 2, 3 ...

  2. 非 ASCII 字符,例如 £¬

  3. 还有在 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/

相关文章:

c# - 无法按价格对下拉列表进行排序

.net - VB.net - 从 mysql 数据库直接插入/检索图片到/从 Picturebox

c# - 在单个 exe 中捆绑 .net exe、dll、.net 环境和 native dll

c# - 如何遍历通用 List<T> 并按 3 项进行分组

c# - ASP.NET 控件可见性困境

c# - DataGridView 中的动态按钮列

c# - 在 .NET 中粉碎文件

c# - 单一方法的管理员权限

c# - 为什么我可以在 Linq to XML 查询中使用 (string) 而不是 "as string"?

asp.net - 如何有效地在 bundle 中添加 .min 和 .debug 文件