在项目中,在Action执行前或者执行后,通常我们会做一些特殊的操作(比如身份验证,日志,异常,行为截取等)。
微软并不想让MVC开发人员去关心和写这部分重复的代码,所以在MVC项目中我们就可以直接使用它提供的Filter的特性帮我们解决。
在项目中的Models文件夹中创建一个特性类,MyActionFilterAttribute.cs特性类必须以Attribute结尾。
继承System.Web.Mvc.ActionFilterAttribute抽象类,并重写其中的四个方法。
添加一个Home控制器,在Index的Action头部添加[MyActionFilter]过滤器声明。代码如下:
过滤器还可以添加在控制器级别。在HomeController头部添加,可以给整个HomeController内部的所有的Action添加过滤功能。
如果同时在控制器与Action上都设置了过滤器,离的近的优先级别更高。 想要全局网站每个页面都应用过滤器,可以在App_Start目录中的FilterConfig.cs类中添加全局的过滤器,代码如下:
虽然设为全局的过滤器,但是按照优先级别每一个Action或ActionResult执行前后都会匹配到最近(优先级最高)的一个过滤器执行,如果我们希望所有的过滤器都执行,我们可以在特性类上打上标签。
异常过滤器
MVC站点出现异常的时候,会自动执行异常过滤器中的方法。
在FilterConfig.cs中,MVC已经将一个异常过滤器定义成全局的了 filters.Add(new HandleErrorAttribute()); 转到定义查看:
其中包含一个可以重写的虚方法。 public virtual void OnException(ExceptionContext filterContext);
将自己写的异常过滤器注册到全局。
然后在控制器的Action手动抛出异常 throw new Exception(“测试异常过滤”);
Ctrl+F5运行项目,访问你添加异常的Action测试一下。(F5运行会将异常抛出)
身份验证的案例:
Model中:
public class MyFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); HttpContextBase http = filterContext.HttpContext; //HttpContext.Current if (http.Request.Cookies["name"] == null) //如果名字为空,就去/FilterDemo/Index这里 http.Response.Redirect("/FilterDemo/Index"); //HttpContext.Current.Server //string name = HttpContext.Current.Request.Cookies["name"].Value; //有名字 //对cookies里面的值解下码 string msg = http.Server.UrlDecode(http.Request.Cookies["name"].Value) + "用户" + DateTime.Now.ToString() + "时间" + http.Request.RawUrl + "地址 "; StreamWriter sw = File.AppendText(@"E:log.txt"); //如果没有log.txt文件就创建,有的话就追加在后面 sw.Write(msg);//将字符串写入流 sw.Flush();//清理缓存 sw.Dispose();//释放流 } }
Controller:
public class FilterDemoController : Controller { // // GET: /FilterDemo/ public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(string name) { ViewBag.name = name; Response.Cookies["name"].Value = Server.UrlEncode(name); //对中文进行编码,Cookies里面存的就是编码完成后的内容 return View(); } [MyFilter] //对此方法进行过滤 public ActionResult List() { string name=Server.UrlDecode(Request.Cookies["name"].Value); //用Cookies的时候解码下 ViewBag.name =name; return View(); } }
Index:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> <h1>首页 @ViewBag.name</h1> <hr /> @Html.ActionLink("Goto list....", "list"); <form action="@Url.Action("Index")" method="post"> <input type="text" name="name" value=" " /> <input type="submit" value="登入" /> </form> </div> </body> </html>
List:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>List</title> </head> <body> <div> <h1>详细页 </h1> <hr /> <div>@ViewBag.name 这是数据....</div> </div> </body> </html>