HttpRequest的QueryString属性 的一点认识

我们开发asp.net程序获取QueryString时,经常性的遇到一些url编码问题,如:

当然我们一般都是按照提示来把framework版本设置2.0来解决。为什么可以这么解决了,还有没有其它的解决方法了。

先让我们看看QueryString的源代码吧:

  先让我们插入一点 那就是QueryString默认已经做了url解码。  其中HttpValueCollection的 FillFromEncodedBytes方法如下

从这里我们可以看到QueryString已经为我们做了解码工作,我们不需要写成  HttpUtility.HtmlDecode(Request.QueryString["xxx"])而是直接写成Request.QueryString["xxx"]就ok了。

现在让我们来看看你QueryString的验证,在代码中有

if (this._flags[1])
        {
            this._flags.Clear(1);
            this.ValidateNameValueCollection(this._queryString, RequestValidationSource.QueryString);
        }
一看this.ValidateNameValueCollection这个方法名称就知道是干什么的了,验证QueryString数据;那么在什么情况下验证的了?

让我们看看this._flags[1]在什么地方设置的:

  而该方法在ValidateInputIfRequiredByConfig中调用,调用代码

internal void ValidateInputIfRequiredByConfig()
    {
       .........
        if (httpRuntime.RequestValidationMode >= VersionUtil.Framework40)
        {
            this.ValidateInput();
        }

    }

该方法是在HttpApplication中的private Exception ValidateHelper(HttpContext context)和它的内部类ValidateRequestExecutionStep构造函数中调用的。为什么这里会有两次调用我想大家应该很清楚,在IIS7有一个集成和经典模式吧,因为asp.net在管道处理中也有两套。
我想现在大家都应该明白为什么错题提示让我们把framework改为2.0了吧。应为在4.0后才验证。这种解决问题的方法是关闭验证,那么我们是否可以改变默认的验证规则了?

让我们看看ValidateNameValueCollection

  

  哦?原来一切都明白了,验证是在RequestValidator做的。

主要的验证方法还是在CrossSiteScriptingValidation.IsDangerousString(value, out validationFailureIndex);而CrossSiteScriptingValidation是一个内部类,无法修改。

让我们看看CrossSiteScriptingValidation类大代码把

  结果我们发现&#  <! </ <? <[a-zA-z] 这些情况验证都是通不过的。

所以我们只需要重写RequestValidator就可以了。RequestValidator的默认设置在HttpRuntime类中,调用顺序

ProcessRequest(HttpWorkerRequest wr)->ProcessRequestNoDemand(HttpWorkerRequest wr)
->ProcessRequestNow(HttpWorkerRequest wr)->ProcessRequestInternal(HttpWorkerRequest wr)
->EnsureFirstRequestInit(HttpContext context)->FirstRequestInit(HttpContext context)

  

例如我们现在需要处理我们现在需要过滤QueryString中k=&...的情况

public class CustRequestValidator : RequestValidator
   {
       protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
       {
           validationFailureIndex = 0;
           //我们现在需要过滤QueryString中k=&...的情况
           if (requestValidationSource == RequestValidationSource.QueryString&&collectionKey.Equals("k")&& value.StartsWith("&"))
           {
               return true;
           }
           return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
       }
   }

  <httpRuntime requestValidationType="MvcApp.CustRequestValidator"/>

个人在这里只是提供一个思想,欢迎大家拍砖!

posted on   dz45693  阅读(5029)  评论(12编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

导航

< 2012年11月 >
28 29 30 31 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示