System.Uri查询字符串中的文字&符号

时间:2010-05-20 09:22:31

标签: .net escaping uri query-string

我正在开发一个客户端应用程序,它使用一个宁静的服务来查找公司名称。 重要的是我能够在查询中包含文字&符号,因为这个字符在公司名称中很常见。

但是每当我将%26(URI转义的&符号)传递给System.Uri时,它会将其转换回常规的&符号!仔细观察,只有两个未转换回来的字符是散列(%23)和百分比(%25)。

假设我想搜索名为“Pierce& Pierce”的公司:

var endPoint = "http://localhost/companies?where=Name eq '{0}'";
var name = "Pierce & Pierce";
Console.WriteLine(new Uri(string.Format(endPoint, name)));
Console.WriteLine(new Uri(string.Format(endPoint, name.Replace("&", "%26"))));
Console.WriteLine(new Uri(string.Format(endPoint, Uri.EscapeUriString(name))));
Console.WriteLine(new Uri(string.Format(endPoint, Uri.EscapeDataString(name))));

以上所有四种组合都会返回:

http://localhost/companies?where=Name eq 'Pierce & Pierce'

这会导致服务器端出错,因为&符号被(正确地)解释为查询arg分隔符。我真正需要它返回的是原始字符串:

http://localhost/companies?where=Name eq 'Pierce %26 Pierce'

如何在不丢弃System.Uri的情况下解决此问题? 我不能在最后一刻用%26替换所有的&符号,因为通常会涉及多个查询参数,我不想破坏它们的分隔符。

注意: this question中讨论了类似的问题,但我特别指的是System.Uri

3 个答案:

答案 0 :(得分:10)

不仅URL中的&符号不正确。有效的网址不能包含空格。

EscapeDataString方法可以正常编码字符串,您应该编码整个值,而不仅仅是名称:

Uri.EscapeDataString("Name eq 'Pierce & Pierce'")

结果:

Name%20eq%20'Pierce%20%26%20Pierce'

使用此字符串创建Uri时,它将是正确的。要查看URL,您可以使用AbsoluteUri属性。如果您只是将Uri转换为字符串(调用ToString方法),则该网址将被取消转义,因此显示不正确。

答案 1 :(得分:0)

我说的是同样的问题。虽然查询字符串是使用Uri.EscapeDataString进行转义的,但属性AbsoluteUri确实正确地表示它,但WebBrowser以非转义格式发送Uri。

  currentUri = new System.Uri(ServerAgent.urlBase + "/MailRender?uid="
+ Uri.EscapeDataString(uid);

webBrowser.Navigate(currentUri);

加号('+')转换为%2B,但服务器仍然在URL中获取+,然后通过HttpServeletRequest.getParameter()调用将其转换为空格('')

答案 2 :(得分:0)

我通过创建Uri的派生类

解决了这个问题
    class Uri2 : System.Uri
{
    public Uri2(string url) : base(url)
    {
    }

    public override string ToString()
    {
        return AbsoluteUri;
    }
}

在任何地方使用System.Uri,使用Uri2替换。 我不知道这是否是.NetCF的错误,WebBrowser应该以编码格式发送URL,即AbsoluteUri的值,但不是来自ToString()的值