首页 > 代码库 > MVC 过滤器

MVC 过滤器

在项目中,在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 + "地址\r\n";
            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 = http://www.mamicode.com/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=http://www.mamicode.com/" " />
            <input type="submit"  value=http://www.mamicode.com/"登入" />
        </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>

 

MVC 过滤器