今天突然遇到个默名奇妙的现象,参数"id=25"始终无法解析 :
此前参数传递方式都是:
客户端:
//先通过DES加密,再用Encode编码。
<%# URL.Encode(DES.Encode(Eval("Id").ToString(), DES.SECRET)) %>
服务器:
//先通过DES解密,再用Decode编码。
int.TryParse(URL.Decode(DES.Decode(Request.QueryString["id"], DES.SECRET)), out hotelId);
PS:URL和DES都是封装的类,直接调用的静态方法。
单步调试了一下,原来"25"经过加密编码后返回的字符串为:"gkn+7QsXyP8=" 再通过EnCode编码参数就变成了:"gkn%2b7QsXyP8%3d"
这里面有个很特别的字符"+"!因为,在url中+表示空格,通过Reflector工具调试到UrlDecode内部方法可以很容易的看出这一点,页面底部是调试得来的代码,红色部分写的很清楚。
此时查看QueryString 可以看到: Request.QueryString = {id=gkn+7QsXyP8%3d}
执行:Request.QueryString["id"].ToString()后得到的值却是:"gkn 7QsXyP8="。可以看出+变成了空格,%3d变成了= 。
找到了问题的原因,下面就是解决办法了:Request.QueryString["id"].RePlace(" ","+")。
此外:在url中如果出现特殊字符会有一套处理的规则:使用"%+ASCII值"的形式来替代原字符。
例如:+ 转换为%2d 、= 转换为%3d 、? 转换为%3f。值得注意的就是在url中+表示空格
附:UrlDecode反编译后的代码,看得出+的特殊性
private static string UrlDecodeStringFromStringInternal(string s, Encoding e) { int length = s.Length; UrlDecoder decoder = new UrlDecoder(length, e); for (int i = 0; i < length; i++) { char ch = s[i]; //注意这里 if (ch == '+') { ch = ' '; } else if ((ch == '%') && (i < (length - 2))) { if ((s[i + 1] == 'u') && (i < (length - 5))) { int num3 = HexToInt(s[i + 2]); int num4 = HexToInt(s[i + 3]); int num5 = HexToInt(s[i + 4]); int num6 = HexToInt(s[i + 5]); if (((num3 < 0) || (num4 < 0)) || ((num5 < 0) || (num6 < 0))) { goto Label_0106; } ch = (char) ((((num3 << 12) | (num4 << 8)) | (num5 << 4)) | num6); i += 5; decoder.AddChar(ch); continue; } int num7 = HexToInt(s[i + 1]); int num8 = HexToInt(s[i + 2]); if ((num7 >= 0) && (num8 >= 0)) { byte b = (byte) ((num7 << 4) | num8); i += 2; decoder.AddByte(b); continue; } } Label_0106: if ((ch & 0xff80) == 0) { decoder.AddByte((byte) ch); } else { decoder.AddChar(ch); } } return decoder.GetString(); }