【问题标题】:Uri.AbsoluteUri is different than requested URLUri.AbsoluteUri 与请求的 URL 不同
【发布时间】:2016-04-05 13:55:18
【问题描述】:

我使用 HttpUtility.EncodeUrl 对查询字符串参数进行编码。当我向服务器发送请求时,服务器端 Uri.AbsoluteUri 包含---在某些情况下---不同的查询字符串参数值。

例如要转义的数据字符串是

string data = "+-/*.,?!~\"£$%^&*()_{}[]@'#<>\\|`¬;:=";

HttpUtility.EncodeUrl(data) 结果是

%2b-%2f*.%2c%3f!%7e%22%c2%a3%24%25%5e%26*()_%7b%7d%5b%5d%40%27%23%3c%3e%5c%7c%60%c2%ac%3b%3a%3d

但是当请求到达服务器时,HttpRequestMessage.RequestUri.AbsoluteUri 包含不同的字符串:

%2b-%2f*.%2c%3f!~%22%c2%a3%24%25%5e%26*()_%7b%7d[]%40'%23%3c%3e%5c%7c%60%c2%ac%3b:%3d

我需要比较它们的 HMAC 身份验证机制,所以我用函数修复了这个问题

    /// <summary>
    /// Gets escaped request URL string.
    /// </summary>
    /// <param name="uri"></param>
    /// <returns></returns>
    private string GetEscapedRequestUrl(Uri uri)
    {
        /**
         * When client uses HttpUtility.UrlEncode() some chars in Uri.AbsoluteUri on server side are NOT url-endcoded.
         * E.g. +-/*.,?!~"£$%^&*()_{}[]@'#<>\|`¬;:=
         * client-side: %2b-%2f*.%2c%3f!%7e%22%c2%a3%24%25%5e%26*()_%7b%7d%5b%5d%40%27%23%3c%3e%5c%7c%60%c2%ac%3b%3a%3d
         * server-side: %2b-%2f*.%2c%3f!~  %22%C2%A3%24%25%5E%26*()_%7B%7D[  ]  %40'  %23%3C%3E%5c%7C%60%C2%AC%3b:  %3d     //note: spaces are added to show the difference
         */
        string ret = string.Empty;

        StringBuilder sb = new StringBuilder();
        sb.Append(uri.Scheme);
        sb.Append("://");
        sb.Append(uri.Authority);
        sb.Append(uri.LocalPath);
        sb.Append(uri.Query
            .Replace("~", "%7e")
            .Replace("[", "%5b")
            .Replace("]", "%5d")
            .Replace("'", "%27")
            .Replace(":", "%3a")
        );

        ret = sb.ToString();

        return ret;
    }

谁能告诉我,是什么导致了这种差异,如果有更好的方法来处理它,请分享你的想法。

【问题讨论】:

    标签: asp.net-web-api uri asp.net-web-api2 url-encoding


    【解决方案1】:

    我认为在你的 Action 中将参数的类型从 Uri 更改为 string 会解决问题。

    一个小实验:

    public ActionResult Test()
    {
        string data = "+-/*.,?!~\"£$%^&*()_{}[]@'#<>\\|`¬;:=";
    
        return RedirectToAction("GetEncodedParam", new { data = HttpUtility.UrlEncode(data) });
    }
    
    public ActionResult GetEncodedParam(string data)
    {
        var s = HttpUtility.UrlDecode(data); // here it's original string "+-/*.,?!~\"£$%^&*()_{}[]@'#<>\\|`¬;:="
    
        return new ContentResult { Content = s };
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-11
      相关资源
      最近更新 更多