先介绍下什么是过滤器:ASP.NET MVC中的灭一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理,这时就用到了过滤器。
MVC支持的过滤器有四种:Authorization(授权)、Action(行为)、Result(结果)、Exception(异常)
默认实现的过滤器如下:
一、授权过滤器
给Index页面,添加授权过滤器,只有当用户名为admin1和admin,密码是123456时,才可以访问index页面。
1.无参数的授权过滤器
[Authorize] public ActionResult Index() { return View(); } public ActionResult Login(LoginModel login) { if ((login.UserName == "admin1" || login.UserName == "admin") && login.Password == "123456") { FormsAuthentication.SetAuthCookie(login.UserName, false); return Redirect("/Home/Index"); } return View(); }
此时,我们执行捷星程序,会发现报出无授权的错误,如下
这是由于Web.Config 中缺少如下代码:
<authentication mode="Forms"> <forms loginUrl="~/Home/Login" timeout="1"/> </authentication>
此时,再次执行则会跳转至登录界面。
2.有参数的授权过滤器
[Authorize(Users = "admin,admin1")],可以实现和上面无参相同的功能
[Authorize(Users = "admin")],此时,只有UserName为amin时,才会跳转至index页面。
二、HandleError过滤器
1、MVC默认错误页面
定义一个界面抛出异常,此时会进去MVC默认的错误页面,即Views/Shared下的Error.cshtml
//处理错误过滤器HandleError [HandleError(ExceptionType = typeof(Exception))] public ActionResult ThrowError() { throw new Exception("this is ThrowErrorLogin Action Throw"); }
执行结果如下:
2、自定义错误页面
自定义一个错误页面MyError.cshtml
@{ Layout = null; } <!DOCTYPE html> <html> <head> <title>MyErrorPage</title> </head> <body> <div> <p> There was a <b>@Model.Exception.GetType().Name</b> while rendering <b>@Model.ControllerName</b>'s <b>@Model.ActionName</b> action. </p> <p style="color:Red"> <b>@Model.Exception.Message</b> </p> <p>Stack trace:</p> <pre style=" background-color:Orange">@Model.Exception.StackTrace</pre> </div> </body> </html>
此时在方法前加上[HandleError(ExceptionType = typeof(Exception), View = "MyError")],则调用抛出异常的界面,则会跳转至我们自定义的错误界面
三、自定义过滤器
自定义过滤器需要继承ActionFilterAttribute抽象类,重写其中的方法。
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter { // // 摘要: // 初始化 System.Web.Mvc.ActionFilterAttribute 类的新实例。 protected ActionFilterAttribute(); // // 摘要: // 在执行操作方法后由 ASP.NET MVC 框架调用。 // // 参数: // filterContext: // 筛选器上下文。 public virtual void OnActionExecuted(ActionExecutedContext filterContext); // // 摘要: // 在执行操作方法之前由 ASP.NET MVC 框架调用。 // // 参数: // filterContext: // 筛选器上下文。 public virtual void OnActionExecuting(ActionExecutingContext filterContext); // // 摘要: // 在执行操作结果后由 ASP.NET MVC 框架调用。 // // 参数: // filterContext: // 筛选器上下文。 public virtual void OnResultExecuted(ResultExecutedContext filterContext); // // 摘要: // 在执行操作结果之前由 ASP.NET MVC 框架调用。 // // 参数: // filterContext: // 筛选器上下文。 public virtual void OnResultExecuting(ResultExecutingContext filterContext); }
1、不带参数的自定义过滤器
这里定义一个自定义的登录过滤器,用户名和密码为空,或者不为damin和123456,则会跳转至登录页面
public class CheckLogin: ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { HttpCookieCollection CookieCollect = System.Web.HttpContext.Current.Request.Cookies; if (CookieCollect["username"] == null || CookieCollect["password"] == null) { filterContext.Result = new RedirectResult("/Home/Login"); } else { if (CookieCollect["username"].Value != "admin" && CookieCollect["password"].Value != "123456") { filterContext.Result = new RedirectResult("/Home/Login"); } } } }
使用时只需要在方法名前加上[CheckLogin]即可。
2、带参数的自定义过滤器
public class ParamsFilter : ActionFilterAttribute { public string Message { get; set; } public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); filterContext.HttpContext.Response.Write("Action执行之前" + Message + "<br />"); } public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); filterContext.HttpContext.Response.Write("Action执行之后" + Message + "<br />"); } public override void OnResultExecuting(ResultExecutingContext filterContext) { base.OnResultExecuting(filterContext); filterContext.HttpContext.Response.Write("返回Result之前" + Message + "<br />"); } public override void OnResultExecuted(ResultExecutedContext filterContext) { base.OnResultExecuted(filterContext); filterContext.HttpContext.Response.Write("返回Result之后" + Message + "<br />"); } }
这个自定一过滤器定义了一个string类型的参数,使用时在Action上加[ParamsFilter(Message = "test")]
四、如果一个Control中所有的Action都需要用到同一个过滤器,则可以直接在Control上面加此过滤器