没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2008-12-04 11:09:11.000|阅读 1971 次
概述:使用 Request.QueryString 接受参数时,跟编码有关的一些问题
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
使用Request.QueryString接受参数时,跟编码有关的一些问题,我们先来看以下几个请求,看a.aspx页面用Request.QueryString接受到的是啥信息?
页面URL Request.QueryString["info"]接受到的值 案例一 a.aspx?info=%25 % 案例二 a.aspx?info=%bc%bc%ca%f5 ????
情况分析:
案例一
a.aspx?info=%25为何Request.QueryString["info"]接受到的值是 % ,而不是 %25,是因为Request.QueryString替我们在接受到值后,做了一次URL解码。HttpUtility.UrlDecode("%25")的计算结果就是 % 。
上面的这个案例一虽然看起来很简单。但是我们在一些特殊场景时候,就会因为这个而极度郁闷。
比如以下几种情况:
你有一个自己的加密算法,而这个加密算法,某些情况下会计算出带百分号的结果,而这个结果你是要通过url参数的方式传递给其它页面的。这时候你就苦恼的发现,某些时候某个功能就不能用。如果解决案例一碰到的情况呢?
解决方案一:
把需要传递的参数传递前作一次HttpUtility.UrlEncode,记得是按照UTF-8的编码的UrlEncode。这样如果我们希望客户端接受到的是%25 就应该传递的是%2525 。
切记,不可在接受方每次接受后,自作聪明的都做一次UrlEncode。而是在发送方做UrlEncode。如果接受方接受后作UrlEncode的话,就会出现下面情况:
另:这套方案中切记,UrlEncode和UrlDecode的次数应该一一对应。不能多一次,也不能少一次。有人就会说,这还会出现次数不对应么? 比如下面情况,一个不留意就很可能出现次数不对应。而出现不是你所期望的情况。比如我们有这样类似的功能:
a.aspx页面中,根据传入的from参数,自动跳转到from参数(用Request.QueryString["from"]来接受这个参数)设置的页面。
b.aspx页面也是同样的逻辑,根据传入的from参数(用Request.QueryString["from"]来接受这个参数),自动跳转到指定的页面。
c.aspx页面也是同样的逻辑,根据传入的from参数(用Request.QueryString["from"]来接受这个参数),自动跳转到指定的页面。
这样我们就可能书写下面的链接地址:
a.aspx?from=b.aspx
a.aspx?from=b.aspx?from=c.aspx
a.aspx?from=b.aspx?from=c.aspx?from=http://blog.joycode.com/ghj/
下面再复杂一点,我给下面几个链接,其中都有a这个参数,请告诉我a这个参数是被那个页面接受到了?
说明: HttpUtility.UrlEncode("&") == "%26" HttpUtility.UrlEncode("%") == "%25"
地址 a 参数会被那个页面接受到
a.aspx?from=b.aspx?from=c.aspx&a=1 a 参数被 a.aspx 页面接受到了
a.aspx?from=b.aspx?from=c.aspx%26a=1 a 参数被 b.aspx 页面接受到了
a.aspx?from=b.aspx?from=c.aspx%2526a=1 a 参数被 c.aspx 页面接受到了
如果想不明白,就想想下面这句话
每一次用Request.QueryString获取参数时候,就作了一次HttpUtility.UrlDecode。
解决方案二:
不用Request.QueryString,而是自己实现一个获取查询参数的方法。细节我在案例二讲完后再告诉大家,因为这个解决方案也处理了案例二的一些情况。
案例二
a.aspx?info=%bc%bc%ca%f5传给我们的信息其实是使用GB2312编码后的“技术”这两个汉字。不信,你可以用下面表达式计算的结果就是%bc%bc%ca%f5 HttpUtility.UrlEncode("技术", System.Text.Encoding.GetEncoding("GB2312")) asp.net系统内部,在处理Request.QueryString等情况时候,都是使用的UTF-8的编码,我们如果不存在多系统并存的问题时候,这个问题一点都不存在。但是,当需要跟其它系统交互式后,问题就可能会出现。如果你不了解案例二这里情况时,你就会被这个问题苦恼死。
比如下面这两个地址提到的问题:
asp.net中的server.urlencode函数和asp中的server.urlencode函数返回的值竟然不一样,php与aspx之间中文通过url如何传递?
案例二的解决方案
使用带编码的 HttpUtility.ParseQueryString 函数
就是采用类似下面代码的方式,来获得指定格式编码的查询文本参数。
System.Collections.Specialized.NameValueCollection nv =
System.Web.HttpUtility.ParseQueryString(Request.Url.Query, System.Text.Encoding.GetEncoding("GB2312"));
Response.Write(nv["Tag"]);
要说我为啥知道上面几种解决方案,是因为我用 Reflector 看了 Request.QueryString 的实现代码。在查看代码时候,我们会看到这样一个 internal 方法:
System.Web.HttpValueCollection 类的内部方法:
internal void FillFromString(string s, bool urlencoded, Encoding encoding)
这个内部方法实现了,按需解密查询参数的功能,但是遗憾的是,在querystring 的处理函数中,强制指定了解析 QueryString 时,必须作一次 HttpUtility.UrlDecode。参看如下代码:
public static NameValueCollection ParseQueryString(string query, Encoding encoding)
{
...
return new HttpValueCollection(query, false, true, encoding);
}
如果我们不想采用案例一的解决方案一,我们就需要自己写一个解析查询信息的代码。我们完全可以照抄 System.Web.HttpValueCollection 类的 internal void FillFromString(string s, bool urlencoded, Encoding encoding) 方法来改写。但郁闷的是:如果你用 Reflector 察看这个函数的实现时候,Reflector 出来的代码是错误的。正确的方法如下:是在施凡帮助下完成的。
自己实现从 URL 查询文本 Query 中解析出我们自己需要的文本的方法
/// <summary>
/// 根据 URL 中的 查询文本 Query 解析成一个 NameValueCollection
/// 在装配脑袋帮助下 郭红俊 改编自 System.Web.HttpValueCollection 类的内部方法:
/// internal void FillFromString(string s, bool urlencoded, Encoding encoding)
/// </summary>
/// <param name="query">需要解析的查询文本</param>
/// <param name="urlencoded">解析文本时候是否需要URL解码</param>
/// <param name="encoding">解析文本时候,按照那种URL编码进行解码</param>
/// <returns></returns>
public static NameValueCollection FillFromString(string query, bool urlencoded, Encoding encoding)
{
NameValueCollection queryString = new NameValueCollection();
if (string.IsNullOrEmpty(query))
{
return queryString;
}
// 确保 查询文本首字符不是 ?
if (query.StartsWith("?"))
{
query = query.Substring(1, query.Length - 1);
}
int num1 = (query != null) ? query.Length : 0;
// 遍历每个字符
for (int num2 = 0; num2 < num1; num2++)
{
int num3 = num2;
int num4 = -1;
while (num2 < num1)
{
switch (query[num2])
{
case '=':
if (num4 < 0)
{
num4 = num2;
}
break;
case '&':
goto BREAKWHILE;
}
num2++;
}
BREAKWHILE:
string name = null;
string val = null;
if (num4 >= 0)
{
name = query.Substring(num3, num4 - num3);
val = query.Substring(num4 + 1, (num2 - num4) - 1);
}
else
{
val = query.Substring(num3, num2 - num3);
}
if (urlencoded)
{
queryString.Add(HttpUtility.UrlDecode(name, encoding), HttpUtility.UrlDecode(val, encoding));
}
else
{
queryString.Add(name, val);
}
if ((num2 == (num1 - 1)) && (query[num2] == '&'))
{
queryString.Add(null, string.Empty);
}
}
return queryString;
}
用上面的代码,我们就可以按需解析自己需要的查询参数,而不是受限的使用request.querystring 。
小结
Request.QueryString 替我们件事情:每次接受到参数后,都做 UrlEncode ,并且是按照 UTF-8编码做的 UrlEncode 。 这在大多数情况下没有任何问题,但是一些情况下,会给我们带来麻烦,本文就是分析这些可能给我们带来麻烦的场景,以及解决方法。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:网络转载面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号