一、自定义Filter

自定义Filter需要继承ActionFilterAttribute抽象类,重写其中需要的方法,来看下ActionFilterAttribute类的方法签名。
    //表示所有操作-筛选器特性的基类
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
{
protected ActionFilterAttribute();
//在Action执行之前由 MVC 框架调用。
public virtual void OnActionExecuting(ActionExecutingContext filterContext);
//在Action执行之后由 MVC 框架调用。
public virtual void OnActionExecuted(ActionExecutedContext filterContext);
//在执行Result之前由 MVC 框架调用。
public virtual void OnResultExecuting(ResultExecutingContext filterContext);
//在执行Result后由 MVC 框架调用。
public virtual void OnResultExecuted(ResultExecutedContext filterContext);
}

过滤器代码

    //自定义过滤器
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class LoginFilterAttribute : ActionFilterAttribute
{
ILogger log = LoggerFactory.GetChannelLog(typeof(LogInAuthorizeAttribute)); /// <summary>
/// 默认登录页面
/// </summary>
private static readonly string logUrl = ConfigFactory.WebEnvConfig.Items["LoginToGMS"]; //通过配置cookie名称
private static readonly string cookieName = ConfigFactory.WebEnvConfig.Items["CookieName"]; public override void OnActionExecuting(ActionExecutingContext filterContext)
{
try
{
log.Debug("自定义Cookie名称,CookieName:" + cookieName); var cookie = filterContext.HttpContext.Request.Cookies[cookieName]; if (cookie == null)
{
RedirectUrl(filterContext, logUrl);
}
log.Debug("cookieName:" + cookieName + "cookieValue:" + cookie.Value);
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket == null || string.IsNullOrEmpty(ticket.UserData)) {
log.Debug("解密失败! tick is null or ticket UserData is null :");
RedirectUrl(filterContext, logUrl);
}
log.Debug("解密成功!tick:" + ticket.Name);
LoginUser userData = JsonConvert.DeserializeObject<LoginUser>(ticket.UserData);
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new System.Web.Security.FormsIdentity(ticket),new string[]);
log.Debug("!HttpContext.Current.Request.IsAuthenticated:" + HttpContext.Current.Request.IsAuthenticated);
log.Debug("获取成功! Name:" + userData.User_Nm);
}
catch (Exception ex)
{
log.Error("解密cookie异常:"+ex.Message);
log.Error(ex);
filterContext.HttpContext.Response.Cookies.Clear();
RedirectUrl(filterContext, logUrl);
}
base.OnActionExecuting(filterContext);
} /// <summary>
/// 跳转报错解决办法
/// </summary>
/// <param name="url"></param>
public void RedirectUrl(ActionExecutingContext filterContext, string url)
{
filterContext.HttpContext.Response.Clear();//这里是关键,清除在返回前已经设置好的标头信息,这样后面的跳转才不会报错
filterContext.HttpContext.Response.BufferOutput = true;//设置输出缓冲
if (!filterContext.HttpContext.Response.IsRequestBeingRedirected)//在跳转之前做判断,防止重复
{
//filterContext.HttpContext.Response.Redirect(url, true);//在Filter中用Response.Redirect,虽然URL是跳转了,但是之后的Filter和Action还是会执行,不仅浪费资源,还会产生一些不必要的错误
filterContext.Result = new RedirectResult(url);
}
}

注意过滤器也可以放在整个Controller类的顶部,表示该Controller下的所有Action都执行该项检查。这样一来,控制器里的代码非常漂亮,再也不用所有的Action里都充斥着判断登录的代码了。

顺便说下登录成功后如何将用户信息写入Cookie中

   LoginUser loginUser = new LoginUser();
loginUser.UserId = userfile.User_Id;
loginUser.User_Cd = userfile.User_Cd;
loginUser.User_Nm = userfile.User_Nm; FormsAuthentication.SetAuthCookie(UserName, false);
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(, UserName, DateTime.Now, DateTime.Now.AddTicks(FormsAuthentication.Timeout.Ticks), false, JsonConvert.SerializeObject(loginUser));
string HashTicket = FormsAuthentication.Encrypt(Ticket);
HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket); UserCookie.Domain = FormsAuthentication.CookieDomain;
UserCookie.Path = "/";

同时在Web.config中配置如下:

<authentication mode="Forms">
<forms path="/" loginUrl="/login" defaultUrl="/" protection="All" name=".newpower" domain="" timeout="" slidingExpiration="true" />
</authentication>

二、带参数的自定义Filter

首先,还是按照之前添加自定义过滤器的方法,添加一个自定义过滤器,只是里面多了一个属性,代码如下:

public class FilterAttribute : 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 />");
}
}

然后在调用过滤器的时候,添加上该参数,Controller代码如下:

[Filter(Message="刘备")]  //参数给上
public ActionResult Index()
{
return View();
}

如果标签打到Controller上的话,FilterAttribute将作用到Controller下的所有的Action。

默认情况下Action上打了某个自定义标签后,虽然在Controller上也打上了此标签,但它只有Action上的标签起作用了。
补充:如果Action没有打上该标签,那么Controller上的标签便会被执行。

如果想让Action上的标签执行一次,然后Controller上的标签也执行一次,那么应该如何操作呢?

我们只需在FilterAttribute类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]即可【下面类的最上面红色字体部分】,也就是让其成为可以多次执行的Action。代码如下:

[AttributeUsage(AttributeTargets.All,AllowMultiple = true)]
public class FilterAttribute : ActionFilterAttribute
{
public string Message { get; set; }
......

三、全局过滤器 

创建一个全局action过滤器  (在appstart  的 filterconfig中注册   filters.Add(new LoginFilterAttribute());)

这样就每个Action都会执行此过滤器,而不必每个Controller顶部都加上标签。

public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
//注册全局过滤器
filters.Add(new LoginFilterAttribute() { Message = "全局" });
}
}

MVC之自定义过滤器(ActionFilterAttribute)的更多相关文章

  1. MVC之 自定义过滤器(ActionFilterAttribute)

    一.自定义Filter 自定义Filter需要继承ActionFilterAttribute抽象类,重写其中需要的方法,来看下ActionFilterAttribute类的方法签名. //表示所有操作 ...

  2. MVC之 自定义过滤器(Filter)

    MVC之 自定义过滤器(Filter) 一.自定义Filter 自定义Filter需要继承ActionFilterAttribute抽象类,重写其中需要的方法,来看下ActionFilterAttri ...

  3. asp.net MVC之 自定义过滤器(Filter) - shuaixf

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration :缓存的时间, 以 ...

  4. asp.net MVC之 自定义过滤器(Filter)

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration:缓存的时间,以秒为 ...

  5. [转]MVC之 自定义过滤器(Filter)

    本文转自:http://www.cnblogs.com/kissdodog/archive/2013/01/21/2869298.html 一.自定义Filter 自定义Filter需要继承Actio ...

  6. 利用MVC的自定义过滤器FilterAttribute、IActionFilter、IExceptionFilter实现异常处理等功能

    今天在博客园上看了一篇推荐文章,还说得蛮有道理: http://www.cnblogs.com/richieyang/p/4779028.html 项目中确实有各种后台验证过程,最常见的莫过于判空,而 ...

  7. MVC 自定义过滤器/特性来实现登录授权及验证

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精    最近在做自学MVC,遇到的问题很多,索性一点点总结 ...

  8. MVC系统过滤器、自定义过滤器

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration:缓存的时间,以秒为 ...

  9. ASP.NET MVC 系统过滤器、自定义过滤器

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration:缓存的时间,以秒为 ...

随机推荐

  1. easy-table-vue+VueJs、SpringBoot+Mybatis实现MVVM模型前后台数据交互

    该项目分为前端展示部分和后台服务部分. 前端部分 使用的技术是:NodeJs.Webpack.VueJs 使用的组件库是:IVIEW.easy-table-vue 使用的开发工具是:WebStorm ...

  2. centos7 浏览器(firefox)中文乱码

    主要问题在于firefox用了系统没有的字体 百度的方案: 通过yum安装中文字体 (找不到对应的库) 修改firefox的默认字体(尴尬.不知道改哪个才有效) 粗暴的解决方案: 把 windows ...

  3. [bzoj 5143][Ynoi 2018]五彩斑斓的世界

    传送门 Descroption 给了你一个长为n的序列a,有m次操作 1.把区间[l,r]中大于x的数减去x 2.查询区间[l,r]中x的出现次数 Solution 分块 对于每个块,我们都分别维护: ...

  4. ansible 问题记录(2)

    普通用户执行ansible,但是在远程需要root权限,这个时候执行ansible命令报如下错误: 经分析是由于sudo的时候,普通用户没有在sudoer文件 2.在playbook里面使用sudo认 ...

  5. SSM框架的配置Spring+Springmvc +Mybatis

    ssm框架是由spring mvc +spring+mybatis组成 快速阅读 通过spring的配置文件spring.xml,在servlet中指定spring mvc的配置文件spring-mv ...

  6. linux的常见目录

    常见的目录和作用 目录名 目录名的作用 /bin/ 存放系统命令的目录,普通用户和root都使用,不过放在bin/命令下的单用户模式也可执行 /sbin/ 保存于系统环境相关的命令,只有root可以使 ...

  7. OpenVirtex安装

    目录 环境 安装 环境 我使用的java以及maven版本如下: jdk7下载地址:https://www.oracle.com/technetwork/java/javase/downloads/j ...

  8. TynSerial自定义对象的序列(还原)

    TynSerial自定义对象的序列(还原) TynSerial是咏南中间件封装的支持数据二进制序列(还原)的类. 对于ORM来说,序列类必须序列(还原)自定义对象. 1)定义一个自定义对象 type ...

  9. Flutter移动电商实战 --(52)购物车_数据模型建立和Provide修改

    根据json数据生成模型类 {"goodsId":"2171c20d77c340729d5d7ebc2039c08d","goodsName" ...

  10. java内存空间简述

    JVM的内存空间: 1. 寄存器 (Registers):最快的保存区域,位于处理器内部,由编译器分配.主要作用是记录当前线程所执行的字节码的行号.字节码解释器工作时就是通过改变当前线程的程序计数器选 ...