MVC 自定义拦截器 IActionFilter(或ActionFilterAttribute)、IExceptionFilter(或HandleErrorAttribute)
2013-03-19 17:35
387 查看
英文学习:Filter [ˈfɪltɚ] 拦截器
全局过滤器:FilterConfig.cs https://www.cnblogs.com/webapi/p/5669057.html
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new LoggerFilter());
}
}filters.Add();
MVC 拦截器
典型的AOP(面向切面编程)。厨师可以看成是业务组件,它有个方法就是“炒菜”,但是炒菜前要切菜,炒完了要有人送菜,可这不是厨师该关心的事啊!于是我们的切菜工和服务员就相当于拦截器,其中切菜工在炒菜前拦截,进行切菜,服务员在炒菜后拦截,负责送菜。当然,我们还有个异常拦截器:处理问题的人,就是那个当厨师发现肉变质了喊一声,就来处理的人。
在ASP.NET MVC中,有三种拦截器:Action拦截器、Result拦截器和Exception拦截器。
我要用到第一种和第三种。其实所谓的
ASP.NET MVC拦截器,也没什么神秘的,就是一个普通的类而已。只不过需要继承FilterAttribute基类(如果不继承,就不能做为特性来使用),
Action拦截器还要实现IActionFilter接口,Result拦截器需要实现IResultFilter接口,Exception拦截器需要实现IExceptionFilter接口。
实例:
公告发布功能添加日志记录能力,即在发布公告前,记录一次,在公告发布成功后,再记录一次。然后还要使得其具备异常处理,即当业务组件出现问题时,跳转到相应的错误页面并显示相应提示。
1、添加日志拦截器(Controllers目录下新建一个Filters目录,然后在Filters下新建LoggerFilter.cs)
或:
public class MyFilter1Attribute:ActionFilterAttribute
{
//该方法会在action方法执行之前调用
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法调用钱执行<br/>");
base.OnActionExecuting(filterContext);
}
//该方法会在action方法执行之后调用
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write("我是OnActionExecuted,我在action方法调用后执行<br/>");
base.OnActionExecuted(filterContext);
}
}
2、添加异常拦截器(在Filters下新建ExceptionFilter.cs)
或:
public class MyFilter3Attribute:HandleErrorAttribute
{
//在程序中任何地方出现异常都会执行
public override void OnException(ExceptionContext filterContext)
{
//获取异常对象
Exception ex = filterContext.Exception;
//记录错误日志
//导向友好错误界面
filterContext.Result = new RedirectResult("/Home/Index");
//重要!!告诉系统异常已处理!!如果没有这个步骤,系统还是会按照正常的异常处理流程走
filterContext.ExceptionHandled = true;
//base.OnException(filterContext);
}
}
3、应用拦截器 AnnounceController.cs
4、其它视图页:
(1)、Release.cshtml
微软AJAX客户端数据验证类:MicrosoftAjax.debug.js
Jquery类:jquery-1.7.1.js
(2)、ReleaseSucceed.cshtml
全局过滤器:FilterConfig.cs https://www.cnblogs.com/webapi/p/5669057.html
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new LoggerFilter());
}
}filters.Add();
MVC 拦截器
典型的AOP(面向切面编程)。厨师可以看成是业务组件,它有个方法就是“炒菜”,但是炒菜前要切菜,炒完了要有人送菜,可这不是厨师该关心的事啊!于是我们的切菜工和服务员就相当于拦截器,其中切菜工在炒菜前拦截,进行切菜,服务员在炒菜后拦截,负责送菜。当然,我们还有个异常拦截器:处理问题的人,就是那个当厨师发现肉变质了喊一声,就来处理的人。
在ASP.NET MVC中,有三种拦截器:Action拦截器、Result拦截器和Exception拦截器。
我要用到第一种和第三种。其实所谓的
ASP.NET MVC拦截器,也没什么神秘的,就是一个普通的类而已。只不过需要继承FilterAttribute基类(如果不继承,就不能做为特性来使用),
Action拦截器还要实现IActionFilter接口,Result拦截器需要实现IResultFilter接口,Exception拦截器需要实现IExceptionFilter接口。
实例:
公告发布功能添加日志记录能力,即在发布公告前,记录一次,在公告发布成功后,再记录一次。然后还要使得其具备异常处理,即当业务组件出现问题时,跳转到相应的错误页面并显示相应提示。
1、添加日志拦截器(Controllers目录下新建一个Filters目录,然后在Filters下新建LoggerFilter.cs)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MyPeb.Mvc.Controllers.Filters { //Action拦截器(拦截Action的上下文) public class LoggerFilter : FilterAttribute, IActionFilter { //OnActionExecuting在被拦截Action前执行 void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { filterContext.Controller.ViewData["ExecutingLogger"] = "正要添加公告,已以写入日志!时间:" + DateTime.Now; } //OnActionExecuted在被拦截Action后执行 void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) { filterContext.Controller.ViewData["ExecutedLogger"] = "公告添加完成,已以写入日志!时间:" + DateTime.Now; } } }
或:
public class MyFilter1Attribute:ActionFilterAttribute
{
//该方法会在action方法执行之前调用
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法调用钱执行<br/>");
base.OnActionExecuting(filterContext);
}
//该方法会在action方法执行之后调用
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write("我是OnActionExecuted,我在action方法调用后执行<br/>");
base.OnActionExecuted(filterContext);
}
}
2、添加异常拦截器(在Filters下新建ExceptionFilter.cs)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MyPeb.Mvc.Controllers.Filters { //Exception拦截器(异常处理) public class ExceptionFilter : FilterAttribute, IExceptionFilter { //当然是发生异常时被调用了 void IExceptionFilter.OnException(ExceptionContext filterContext) { filterContext.Controller.ViewData["ErrorMessage"] = filterContext.Exception.Message; filterContext.Result = new ViewResult()//设置异常结果 { ViewName = "Error", ViewData = filterContext.Controller.ViewData, }; filterContext.ExceptionHandled = true;//异常已经处理,不要再次处理了 } } }
或:
public class MyFilter3Attribute:HandleErrorAttribute
{
//在程序中任何地方出现异常都会执行
public override void OnException(ExceptionContext filterContext)
{
//获取异常对象
Exception ex = filterContext.Exception;
//记录错误日志
//导向友好错误界面
filterContext.Result = new RedirectResult("/Home/Index");
//重要!!告诉系统异常已处理!!如果没有这个步骤,系统还是会按照正常的异常处理流程走
filterContext.ExceptionHandled = true;
//base.OnException(filterContext);
}
}
3、应用拦截器 AnnounceController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MyPeb.Mvc.Controllers.Filters; namespace MyPeb.Mvc.Controllers { /// <summary> /// 公告 /// </summary> public class AnnounceController : Controller { //发布公告 // GET: /Announce/Release public ActionResult Release() { List<SelectListItem> select1 = new List<SelectListItem> { new SelectListItem { Text = "公告标题1", Value = "1", Selected=true}, new SelectListItem { Text = "公告标题2", Value = "2" }, }; //生成数据的枚举,绑定到value的字段名,绑定到列表名称的字段名。 ViewData["lb"] = new SelectList(select1, "Value", "Text");//SelectList类型存入ViewData return View("Release");//呈现Release视图 } //处理公告 [LoggerFilter()]//Action拦截器 [ExceptionFilter()]//异常拦截器 public ActionResult DoRelease() { //一、验收数据的合法性 //1、AJAX实现客户端数据验证(在数据被送到后台前,我们应该先进行一遍验证,这样可以节约很多资源) //2、同步方式完成数据验证 if (String.IsNullOrEmpty(Request.Form["content"])) { ViewData.ModelState.AddModelError("contentValidator", "公告内容不能为空!"); return Release();//返回Release方法 } //二、获得表单数据或、处理Bll、展示 ViewData["Announce"] = Request.Form["lb"]; System.Threading.Thread.Sleep(2000);//延迟2秒 ViewData["Time"] = DateTime.Now;//记录了执行此Action的时间 System.Threading.Thread.Sleep(2000); return View("ReleaseSucceed");//呈现ReleaseSucceed视图 } //发布成功 public ActionResult ReleaseSucceed() { return View(); } } }
4、其它视图页:
(1)、Release.cshtml
微软AJAX客户端数据验证类:MicrosoftAjax.debug.js
Jquery类:jquery-1.7.1.js
@{ Layout = null; } <!DOCTYPE html> <html> <head> <title>发布公告</title> @*1、AJAX实现客户端数据验证*@ @*<script type="text/javascript" src="@Url.Content("~/Scripts/MicrosoftAjax.debug.js")"></script>*@@*ASP.NET AJAX的库文件*@ @*Url是ViewPage的一个对象,它最常用的一个方法就是Content,它的功能是返回某个文件的路径*@ @* <script type="text/javascript"> Sys.Application.add_init(onPageInit); function onPageInit() { $addHandler($get("Submit"), "click", validate); } function validate() { if ($get("content").value == "") { $get("ContentValidator2").innerHTML = "内容2不能为空!"; return false; } return true; } </script>*@ @*2、JQuery实现客户端验证*@ <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.7.1.js")"></script> <script type="text/javascript"> $(document).ready(function () { $("#Submit").click(function () { if ($("#content").attr("value") == "") { $("#ContentValidator2").html("内容2不能为空!"); return false; } return true; }); }); </script> </head> <body> @using (Html.BeginForm("DoRelease", "Announce", FormMethod.Post)) { <div> 公告类别:@Html.DropDownList("lb") </div> <div> 公告内容:@Html.TextArea("content") @Html.ValidationMessage("contentValidator")@*同步方式内容验证信息*@ <span id="ContentValidator2"> </span>@*异步方式内容验证信息*@ </div> <div> <input id="Submit" type="submit" value="发布" /> </div> } </body> </html>
(2)、ReleaseSucceed.cshtml
@{ Layout = null; } <!DOCTYPE html> <html> <head> <title>ReleaseSucceed</title> </head> <body> <div> 传递表单数据:@ViewData["Announce"]<br /> 拦截Action前执行:@ViewData["ExecutingLogger"]<br /> 拦截Action后执行:@ViewData["ExecutedLogger"]<br /> 异常错误信息:@ViewData["ErrorMessage"] </div> </body> </html>
相关文章推荐
- MVC扩展Filter,通过继承HandleErrorAttribute,使用log4net或ELMAH组件记录服务端500错误、HttpException、Ajax异常等
- MVC过滤器-->ActionFilterAttribute和HandleErrorAttribute
- MVC之 自定义过滤器(ActionFilterAttribute)
- HandleErrorAttribute的自定义(拦截器的使用)
- mvc中的action验证登录(ActionFilterAttribute)
- ASP.NET MVC 利用ActionFilterAttribute来做权限等
- ASP.NET MVC 4 - ActionExecutedContext&ActionExecutingContext&ActionFilterAttribute
- Attribute(二)——自定义特性+Asp.net MVC中的filter详解
- MVC——ActionFilterAttribute
- Part 72 - HandleError attribute in mvc
- How to use Asp.Net Mvc ActionFilterAttribute for form authentication
- MVC 2中HandleErrorFilter的问题及其解决方法
- Asp.net mvc:使用ActionFilterAttribute记录操作日志
- \t\tASP.NET MVC ActionFilterAttribute
- ASP.NET MVC 利用ActionFilterAttribute来判断用户是否登陆等等
- Asp.net MVC2学习笔记7-拦截器接口(IActionFilter,IExceptionFilter,IResultFilter,IAuthorizationFilter)
- MVC 2中HandleErrorFilter的问题及其解决方法
- Minify Action Filter Attribute in ASP.NET MVC
- MVC中ActionFilterAttribute用法并实现统一授权
- ASP.NET MVC 利用ActionFilterAttribute来做权限等