ASP.NET MVC 中如何用自定义 Handler 来处理来自 AJAX 请求的 HttpRequestValidationException 错误
2013-09-02 14:50 音乐让我说 阅读(1823) 评论(0) 编辑 收藏 举报今天我们的项目遇到问题
为了避免跨站点脚本攻击, 默认我们项目是启用了 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>
谢谢浏览!
作者:音乐让我说(音乐让我说 - 博客园)
出处:http://music.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。