• 深度解析Asp.net中的验证和Mvc对它的继承


    1.HttpRequest.ValidateInput() 只是设置一个标志,这个标志就是_flags[0x8000],是启用验证开关标志(另外还启用了其他一些标志),

      HttpRequest.ValidateInputWasCalled就是根绝这个启用验证开关标志来判断的这个标志很重要,见后面说明。

    2.ValidationUtility.EnableDynamicValidation是调用DynamicValidationShimReflectionUtil(反射垫片),

      DynamicValidationShimReflectionUtil(反射垫片)以反射方式调用DynamicValidationShimDynamicValidationShim调用HttpRequest

      的EnableGranularRequestValidation来设置_enableGranularValidation为true, 表示需要细粒度的验证

     

      这个细粒度的验证的意思:其中,HttpRequest在Form,QueryString,Heads,Cookie,Files的get读取器访问时会调用到以下三个方法:

      HttpRequest的ValidateHttpValueCollection()、ValidateCookieCollection()、ValidatePostedFileCollection()。在调用它们时会判断

      _enableGranularValidation是否为true,

      如果是true则表示启用颗粒级的验证,会等到调用Form,QueryString,File的 Get/this[""](this索引器其实调用的也是Get方法)方法时才会去调用验证函数来验证值,

      如果是false,则一访问Form或QuetyString,Header属性时则就马上调用验证函数

     

    3.而上面说的验证函数实际上就是HttpRequest的ValidateString函数,这个函数主要是调用RequestValidatorIsValidRequestString

       IsValidRequestString是用来验证危险字符的,不过它不会去验证HttpHead,也就是说HttpHeaderCollection的串不论传的是什么格式始终是有效的不会被服务端验证的,

      原因尚待研究。详情见RequestValidatorIsValidRequestString方法。

     

    4.调用到EnableGranularRequestValidation的方法:在ValidationUtility.EnableDynamicValidation() 和

       HttpRequest.ValidateInputIfRequiredByConfig()【.NET4.5有调用到】【.net4.5默认启用细粒度的验证

     

      ValidationUtility.EnableDynamicValidation调用它的几个地方有:

      1、MvcHandler的ProcessRequestInit方法:这个方法会判断HttpRequest的_flags是否设置了已启用验证的位(HttpRequest.RequestValidationCalled),如果已启用,则启用颗粒验证

      2、ControllerActionInvoker的ValidateRequest方法:这个方法总是会被调用, 因为它时根据controllerBase中的ValidateRequest属性是否为true来调用,

         而ValidateRequest总是默认为true,除非使用ValidateInputAttribute来修改这个属性

      3、ValidationUtility的GetUnvalidatedCollections

      4、WebPageHttpHandler的ProcessRequestInternal

     

      而调用HttpRequest.ValidateInputIfRequiredByConfig()调用它的几个地方有

      1、ValidateRequestExecutionStep。

      2、PipelineStepManager

      如果是ValidateInputIfRequiredByConfig总是会去设置

     

      所以是大于.net4.0,总会调用HttpRequest.ValidateInput,这样总是会启用验证(RequestValidationCalled总是为true),而什么时候开始验证,则是判断_enableGranularValidation是否为true

      在MVC3中,因为调用了MvcHandler的ProcessRequestInit方法,ProcessRequestInit又调用EnableDynamicValidation(前提是RequestValidationCalled为true),所以_enableGranularValidation总为true,

      而在webform4.0里,因为没有地方调用EnableDynamicValidation或ValidateInputIfRequiredByConfig,_enableGranularValidation总为false,在webform中如果有非法字符,

      一旦访问Form,Headers或QueryString就会报错

     

      所以ValidateInput的作用貌似是这样,先将HttpRuntime节点的RequestValidationMode设置为2.0,这样RequestValidationCalled的开关被关掉了,

      Mvc执行Action之后,没有地方去调用ValidationUtility.EnableDynamicValidationle了,然后再开启ValidateInputAttribute(true),这样就可以自由控制了

     

    RequestValidationMode:

    2.0 仅对网页启用请求验证。是启用还是关闭取决于页面的 validateRequest。

    4.0 默认值。任何 HTTP 请求都会

     

    HttpRuntimeSection s = ConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection;

    var bi = s.RequestValidationMode;

    FieldInfo fi = typeof(HttpRequest).GetField("_enableGranularValidation", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

    var b = fi.GetValue(System.Web.HttpContext.Current.Request;

     

  • 相关阅读:
    poj 2251 Dungeon Master-搜索进阶-暑假集训
    棋盘问题-POJ 1321
    Popular Cows
    The Factor
    整数解 (hdu 2092
    Strange fuction hdu 2899
    Factors and Multiples
    Trailing Zeroes (III) -;lightoj 1138
    Swap——hdu 2819
    Arithmetic Sequence
  • 原文地址:https://www.cnblogs.com/yuuki/p/3307516.html
Copyright © 2020-2023  润新知