zoukankan      html  css  js  c++  java
  • ASP.NET MVC 中如何用自定义 Handler 来处理来自 AJAX 请求的 HttpRequestValidationException 错误

    今天我们的项目遇到问题

       为了避免跨站点脚本攻击, 默认我们项目是启用了 validateRequest,这也是 ASP.NET 的默认验证规则。项目发布后,如果 customError 启用了,则会显示我们自己定义的错误页面,如果没有,就会显示具体的错误页面,比如:

    如果想忽略这个 ASP.NET 默认的验证规则,则可以在 web.config 中禁用

    <system.web>
     <pages validateRequest="false" />
     </system.web>

    如果是基于 ASP.NET 4.0 的项目,则还需要配置

    <httpRuntime requestValidationMode="2.0"/>

    自定义请求验证处理规则

    由于 ASP.NET 在验证提交的数据时,默认会调用 System.Web.Util.RequestValidator 类的 IsValidRequestString 方法,所以我们可以自定义一个类,继承它,并重写 IsValidRequestString 方法,然后在 web.config 中注册。

    <httpRuntime requestValidationType="TestMvc.MvcUI.Extensions.RequestValidatorDisabled"/>

    如果 RequestValidatorDisabled 类没有继承 System.Web.Util.RequestValidator 类,则应用程序启动时就会报错:

    我们自定义的代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace TestMvc.MvcUI.Extensions
    {
        public class RequestValidatorDisabled : System.Web.Util.RequestValidator
        {
            protected override bool IsValidRequestString(HttpContext context,
                string value,
                System.Web.Util.RequestValidationSource requestValidationSource,
                string collectionKey,
                out int validationFailureIndex)
            {
                validationFailureIndex = -1;
                return true;
            }
        }
    }

    ASP.NET MVC 默认

    这样也符合验证逻辑,想要在自定义错误页面中显示自定义的消息,需要在 MVC 项目中的 Shared/Error.cshtml 中写代码,比如:

    @model System.Web.Mvc.HandleErrorInfo
    
    @{
        ViewBag.Title = "错误";
    }
    
    <div class="errorDiv clearfix">
        <div class="errorImg"></div>
        <div class="errorMsg">
            <p>抱歉,处理您的请求时出错!</p>
            <p>
            @if (Model.Exception is HttpRequestValidationException)
            {
                <span>抱歉!此次请求不允许提交包含 Html 代码的内容(即:< 或 >)!</span>
            }
            else if (Model.Exception is ArgumentException)
            {
                <span>请检查您输入或提交的的 Url 是否正确,或者提交的数据是否正确!</span>
            }
           else 
           { 
               <span>详细:</span>  @Model.Exception.Message;
           }
            </p>
        </div>
    </div>


    这样用户就会清楚地知道,具体的消息是什么。但有一个问题,就是来自 AJAX 的请求,页面会无法响应。于是就开始思考解决方案。

    在 Global.asax 中解决

     想到 Global.asax 中的 Application_Error 中可以定义异常发生后的处理逻辑,于是就有了如下处理方式:

    protected void Application_Error(object sender, EventArgs e)
    {
        if (HandleHttpRequestValidationException())
        {
            return;
        }
    }
    
    /// <summary>
    /// 处理 HttpRequestValidationException
    /// </summary>
    /// <returns>是否错误已经被处理</returns>
    protected bool HandleHttpRequestValidationException()
    {
        if (!(Context.Handler is MvcHandler))
        {
            return false;
        }
        Exception ex = Server.GetLastError();
        if (ex is HttpRequestValidationException)
        {
            HttpRequestWrapper httpRequestWrapper = new HttpRequestWrapper(Request);
            if (httpRequestWrapper.IsAjaxRequest())
            {
                Response.Write(WebCommonHelper.Serialize(new ResultMessage(false, "抱歉!此次请求不允许提交包含 Html 代码的内容(即:< 或 >)!")));
                Response.ContentType = "text/json";
                Server.ClearError();
                return true;
            }
        }
        return false;
    }


    其中 WebCommonHelper.Seriallize 方法是调用了 .NET 内部的 JavaScriptSerializer 来 JSON 序列化。ResultMessage 是我们大部分用来响应 AJAX 请求的模型。

    Javascript 验证

     <script type="text/javascript">
         function validate()
         {
             var text = document.getElementById("TextBox1").value;
             var testArray = text.split('');
    
             var flag = 0;
             for (var a in testArray)
             {
                 if (testArray[a] == '<' && flag == 0)
                 {
                     flag = 1;
                 }
                 if (testArray[a] == '>' && flag == 1)
                 {
                     flag = 2;
                     break;
                 }
             }
             if (flag == 2)
             {
                 alert("不能包含 <html> 标签!");
                 return false;
             }
             return true;
         }
      </script>

    谢谢浏览!

  • 相关阅读:
    jvm09
    jvm08
    jvm07
    求解最长公共子序列问题
    归并排序
    求解N皇后问题
    快速排序算法
    求解0/1背包问题
    求解全排列问题
    求解最大连续子序列和问题
  • 原文地址:https://www.cnblogs.com/Music/p/handle-http-request-validation-exception-from-ajax-in-asp-net-mvc.html
Copyright © 2011-2022 走看看