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 = -;
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>
谢谢浏览!
ASP.NET MVC 中如何用自定义 Handler 来处理来自 AJAX 请求的 HttpRequestValidationException 错误的更多相关文章
- asp.net MVC中如何用Membership类和自定义的数据库进行登录验证
		
asp.net MVC 内置的membershipProvider可以实现用户登陆验证,但是它用的是自动创建的数据库,所以你想用本地数据库数据去验证,是通过不了的. 如果我们想用自己的数据库的话,可以 ...
 - jQuery+ASP.NET MVC基于CORS实现带cookie的跨域ajax请求
		
这是今天遇到的一个实际问题,在这篇随笔中记录一下解决方法. ASP.NET Web API提供了CORS支持,但ASP.NET MVC默认不支持,需要自己动手实现.可以写一个用于实现CORS的Acti ...
 - 在Asp.Net MVC 中如何用JS访问Web.Config中appSettings的值
		
应用场景: 很多时候我们要在Web.Config中添加appSettings的键值对来标识一些全局的信息,比如:调用service的domain,跳转其他网站页面的url 等等: 那么此时就涉及到了一 ...
 - Asp.Net MVC 中的 Cookie(译)
		
Asp.Net MVC 中的 Cookie(译) Cookie Cookie是请求服务器或访问Web页面时携带的一个小的文本信息. Cookie为Web应用程序中提供了一种存储特定用户信息的方法.Co ...
 - ASP.NET MVC 学习笔记-7.自定义配置信息    ASP.NET MVC 学习笔记-6.异步控制器  ASP.NET MVC 学习笔记-5.Controller与View的数据传递  ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用  ASP.NET MVC 学习笔记-3.面向对象设计原则
		
ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...
 - asp.net mvc 中的自定义验证(Custom Validation Attribute)
		
前言
 - 在 ASP.NET MVC 中充分利用 WebGrid (microsoft 官方示例)
		
在 ASP.NET MVC 中充分利用 WebGrid https://msdn.microsoft.com/zh-cn/magazine/hh288075.aspx Stuart Leeks 下载代 ...
 - 在 ASP.NET MVC 中使用 HTML Helpers 的那些事
		
在 ASP.NET MVC 中使用 HTML Helpers 方法,可以返回得到标准的 HTML 标签,就像 <input>.<button> 或者 <img> 等 ...
 - Datatables 在asp.net mvc中的使用
		
前言 最近使用ABP(ASP.NET Boilerplate)做新项目,以前都是自己扩展一个HtmlHelper来完成同步/异步分页,但是有个地方一直不满意,排序太费劲. 以前接触过一点点的Datat ...
 
随机推荐
- java历史集合类对比
 - hibernate(二)一级缓存和三种状态解析
			
序言 前一篇文章知道了什么是hibernate,并且创建了第一个hibernate工程,今天就来先谈谈hibernate的一级缓存和它的三种状态,先要对着两个有一个深刻的了解,才能对后面我要讲解的一对 ...
 - Jquery EasyUI封装简化操作
			
//confirm function Confirm(msg, control) { $.messager.confirm('确认', msg, function (r) { if (r) { eva ...
 - How do I check if a type is a subtype OR the type of an object?
			
To check if a type is a subclass of another type in C#, it's easy: typeof (SubClass).IsSubclassOf(ty ...
 - .net下BerkeleyDB操作封装C#版(附单元测试)
			
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System ...
 - 设置Tomcat编码
			
设置Tomcat编码 <Connector port="8080" maxThreads="150" mi ...
 - 使用cow将socks5代理转为http代理(Windows版)
			
自己租vps架设shadowsocks服务器,再配合chrome的SwitchyOmega插件科学上网一直很稳定,但是windows很多软件都不支持socks5,经常也会需要配置http代理做更新上传 ...
 - python数据结构之二叉树遍历的实现
			
本篇是实现二叉树的三种遍历,先序遍历,中序遍历,后序遍历 #!/usr/bin/python # -*- coding: utf-8 -*- class TreeNode(object): def _ ...
 - IOS , plist 配置项说明
			
本文转载至 http://blog.csdn.net/fengsh998/article/details/8307424 Key:Application can be killed immediate ...
 - Windows 64位 安装Oracle instantclient 官方绿色版和PL/SQL Developer 总结
			
原文: http://blog.csdn.net/kimsoft/article/details/8751267 操作系统:Windows 7 64位旗舰 要求,安装PL/SQL Developer用 ...