您的位置:首页 > 理论基础 > 计算机网络

ASP.NET MVC 中如何用自定义 Handler 来处理来自 AJAX 请求的 HttpRequestValidationException 错误

2013-09-02 14:50 1021 查看

今天我们的项目遇到问题

为了避免跨站点脚本攻击, 默认我们项目是启用了 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>


谢谢浏览!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐