您的位置:首页 > 其它

MVC 自定义拦截器 IActionFilter(或ActionFilterAttribute)、IExceptionFilter(或HandleErrorAttribute)

2013-03-19 17:35 323 查看
英文学习: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)

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>


 

 

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