mvc过滤器详解

1.过滤器介绍

我们知道mvc的运行机制是通过管道完成的,过滤器可以注入一些代码逻辑到请求处理管道中,是基于C#的Attribute的实现。当负责调用Action的类ControllerActionInvoker在调用执行Action的时候会检查Action上面的Attribute并查看这些Attribute是否实现了指定的接口,以便进行额外的代码注入处理。

2.过滤器分类:

MVC支持的过滤器类型有四种,分别是:Authorization(授权),Action(行为),Result(结果)和Exception(异常)。

如下表

 

过滤器类型

接口

描述

Authorization

IAuthorizationFilter

此类型(或过滤器)用于限制进入控制器或控制器的某个行为方法

Exception

IExceptionFilter

用于指定一个行为,这个被指定的行为处理某个行为方法或某个控制器里面抛出的异常

Action

IActionFilter

用于进入行为之前或之后的处理

Result

IResultFilter

用于返回结果的之前或之后的处理

 

但是默认实现它们的过滤器只有三种,分别是Authorize(授权),ActionFilter,HandleError(错误处理);各种信息如下表所示

 

过滤器

类名

实现接口

描述

ActionFilter

AuthorizeAttribute

IAuthorizationFilter

此类型(或过滤器)用于限制进入控制器或控制器的某个行为方法

HandleError

HandleErrorAttribute

IExceptionFilter

用于指定一个行为,这个被指定的行为处理某个行为方法或某个控制器里面抛出的异常

自定义

ActionFilterAttribute

IActionFilter和IResultFilter

用于进入行为之前或之后的处理或返回结果的之前或之后的处理

3.使用授权过滤器

所有实现了IAuthorizationFilter接口的都可以称之为授权过滤器,mvc内置的授权过滤器AuthorizeAttribute,他允许我们使用这个类的两个公共属性来指定授权策略。

 Users和Roles两者是并且的关系,例如Users=“a,b,c”,Roles=“admin”,表示用户是a,b,c 其中一个并且是Admin角色才能访问。

创建自定义授权过滤器

方式一:直接实现IAuthorizationFilter接口,但不推荐这样做,因为牵涉到安全方面的代码。

方式二:继承AuthorizeAttribute这个类,并重写其AuthorizeCore方法,签名为: bool AuthorizeCore(HttpContextBase httpContext),代码如下所示:

public class MyAuthorizeAttribute : AuthorizeAttribute
  {
    private string[] allowedUsers;
    public MyAuthorizeAttribute(params string[] users)
    {
      allowedUsers = new string[] { "admin", "user1", "xf" };
    }
 
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
      return httpContext.Request.IsAuthenticated &&allowedUsers.Contains(httpContext.User.Identity.Name, 
        StringComparer.InvariantCultureIgnoreCase);
    }
  }

4.使用动作过滤器

动作过滤器是实现了IActionFilter接口

该接口定义了两个方法,MVC框架在调用动作方法之前,会调用OnActionExecting方法。在调用动作方法之后,则会调用OnActionExecuted方法。

下面是一个过滤敏感字的动作过滤器:

 

    public class SensitiveWordsFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

           
            bool flag = true;
            if (filterContext.HttpContext.Request.Form.Count > 0)
            {
                foreach (var item in filterContext.HttpContext.Request.Form.AllKeys)
                {

                    if (FuncHelper.isCheck(item.ToString()))
                    {
                        string checkstring = filterContext.HttpContext.Request[item.ToString()];

                        if (!string.IsNullOrEmpty(checkstring))
                        {
                            if (FuncHelper.isInWaring(checkstring))
                            {
                                flag = false;
                            }
                        }
                    }

                }
            }

            if (!flag)
            {
                filterContext.Result = new JsonResult
                {
                    Data = new { IsSuccess = false, State = 0, Msg = "包含敏感字词,请修改", ObjData = new List() },
                };
            }
        }
    }

5.结果过滤器

需要现IResultFilter接口,当结果过滤器运用于一个动作方法时,会在动作方法返回动作结果之前,调用OnResultExecuting方法,在返回动作结果之后,会调用OnResultExecuted方法。

6.异常过滤器

创建自定义异常过滤器必须实现IExceptionFilter接口,当一个未知处理异常发生时,OnException方法会被调用。该方法的传递一个ExceptionContext对象,派生于ControllerContext类。

        public class DExceptionFilterAttribute : ExceptionFilterAttribute
        {
            public override void OnException(HttpActionExecutedContext context)
            {
                //可以记录一些日志
                string fLog = context.Exception.ToString();

                //篡改Response
                context.Response = new HttpResponseMessage(HttpStatusCode.OK);

                JavaScriptSerializer js = new JavaScriptSerializer();
                string r = js.Serialize(new ReturnResult() { State = 500, Msg = "内部程序错误" });

                context.Response.Content = new StringContent(r, Encoding.UTF8, "application/json");
            }
        }

 

你可能感兴趣的:(ASP.Net,MVC,过滤器,mvc)