Asp.net web api Uri.AbsoluteUri与请求的URL不同

Asp.net web api Uri.AbsoluteUri与请求的URL不同,asp.net-web-api,uri,asp.net-web-api2,url-encoding,Asp.net Web Api,Uri,Asp.net Web Api2,Url Encoding,我使用HttpUtility.EncodeUrl对querystring参数进行编码。当我向服务器发送请求时,在服务器端Uri.AbsoluteUri包含——在某些情况下——不同的querystring参数值 例如,要转义的数据字符串为 string data = "+-/*.,?!~\"£$%^&*()_{}[]@'#<>\\|`¬;:="; 但当请求到达服务器时,HttpRequestMessage.RequestUri.AbsoluteUri包含不同的字符串: %2b

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

例如,要转义的数据字符串为

string data = "+-/*.,?!~\"£$%^&*()_{}[]@'#<>\\|`¬;:=";
但当请求到达服务器时,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;
    }
//
///获取转义的请求URL字符串。
/// 
/// 
/// 
私有字符串GetEscapedRequestUrl(Uri)
{
/**
*当客户端使用HttpUtility.UrlEncode()时,服务器端Uri.AbsoluteUri中的一些字符不是url端编码的。
*例如+-/*,?!~“£$%^&*({}[]@'”=
*客户端:%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
*服务器端:%2b-%2f*%2c%3f!~%22%C2%A3%24%25%5E%26*()7B%7D[]%40%23%3C%3E%5c%7C%60%C2%AC%3b:%3d//注意:添加空格以显示差异
*/
string ret=string.Empty;
StringBuilder sb=新的StringBuilder();
sb.Append(uri.Scheme);
某人加上(“:/”);
某人附加(权限);
sb.Append(uri.LocalPath);
sb.Append(uri.Query
.替换(“~”,“%7e”)
.替换(“[”,“%5b”)
.替换(“]”,“%5d”)
.替换(“'”,“%27”)
.替换(“:”,“%3a”)
);
ret=sb.ToString();
返回ret;
}

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

我认为在您的操作中将参数的类型从
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 };
}
公共操作结果测试()
{
字符串数据=“+-/*,?!~\”£$%^&*(){}[]@'\\\\\\\\\\\`,:=”;
返回RedirectToAction(“GetEncodedParam”,new{data=HttpUtility.UrlEncode(data)});
}
公共操作结果GetEncodedParam(字符串数据)
{
var s=HttpUtility.UrlDecode(data);//这里是原始字符串“+-/*,?!~\”£$%^&*()\{}[]@'\\\\\\\\\\\\\`,:=”
返回新的ContentResult{Content=s};
}
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 };
}