代码环境:.Net MVC
我定义了一个PowerAttribute并且让他应用于所有的控制器,另外定义了一个NoFilterAttribute想让某些方法不应用PowerAttribute,比如登录。但是现在我在登录方法上面添加了NoFilterAttribute,他还是会先走PowerAttribute。下面是我的代码,请各位园友指出一下我的错误,谢谢!
public class PowerAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { string targetUrl = "/home/index"; string loginName = CookieHelper.GetCookieValue("loginName"); if (string.IsNullOrEmpty(loginName)) { filterContext.Result = new RedirectResult(targetUrl); } base.OnActionExecuting(filterContext); }
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class NoFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
}
}
Global.asax.cs:
protected void Application_Start() { GlobalFilters.Filters.Add(new PowerAttribute()); GlobalFilters.Filters.Add(new NoFilterAttribute()); }
HomeController:
[NoFilter] public ActionResult Index() { return Content("请登录!"); }
我以前的做法是:在PowerAttribute里判断当前action是否有NoFilterAttribute
有的话直接跳过吗?有没有其他做法,给点想法!当PowerAttribute应用于类时,不用判断直接给方法加NoFilterAttribute也有效果。是不是我在Global里面应用的原因?
@晓菜鸟: 可以试试能不能将特性移除。然后把nofilter的优先级弄最高
@吴瑞祥: 1、如何移除特性?2、如何把nofilter的优先级弄高?
@吴瑞祥: 翔哥,如何判断当前action是否有NoFilterAttribute?
NoFilter肯定是指定只能在action上使用的。
然后要其他过滤器要支持NoFilter的,就得在过滤器里面写上当前action有NoFilter就跳过该过滤器的执行
filterContext.ActionDescriptor.GetFilterAttributes
@吴瑞祥: 其实我觉得问题应该出现在我的全局过滤器上面,他每次都会先执行全局的,所以进不来NoFileter,翔哥,谢了!
设置order属性
执行顺序根据order属性来的
Order?Attribute里面有order属性?
@晓菜鸟:
public abstract class FilterAttribute : Attribute, IMvcFilter { // Summary: // Initializes a new instance of the System.Web.Mvc.FilterAttribute class. protected FilterAttribute(); // Summary: // Gets or sets a value that indicates whether more than one instance of the // filter attribute can be specified. // // Returns: // true if more than one instance of the filter attribute can be specified; // otherwise, false. public bool AllowMultiple { get; } // // Summary: // Gets or sets the order in which the action filters are executed. // // Returns: // The order in which the action filters are executed. public int Order { get; set; } }
@小眼睛老鼠: 这个Order不是你自己定义的?
@晓菜鸟:
在做法上我不建议这么做
我的做法是 加一个排他字典
以确保 全局的前提下排除一些不需要执行的
@晓菜鸟: FilterAttribute 自带的
@小眼睛老鼠: 那这个Order我应该在哪里设置呢?
当PowerAttribute应用于类时,不用判断直接给方法加NoFilterAttribute也有效果。是不是我在Global里面应用的原因?
@晓菜鸟: [NoFilter(Order = 2)]
@小眼睛老鼠: 这个跟在Global里Add的时候设置的Order是一样的吗?
GlobalFilters.Filters.Add(power,2);
@晓菜鸟: 比global里面小或者大 这个决定执行顺序
@小眼睛老鼠: 越大的越先执行是吗?
@晓菜鸟: 自己试
@小眼睛老鼠: 嗯,但是我设置了执行顺序之后我要的功能还是没有实现,我进/home/index方法他还是会照样走PowerAttribute,然后跳转。
@晓菜鸟: filterContext.Result =
@小眼睛老鼠: 你没看我上面给的代码吗?我进入/Home/Index,他还是会走PowerAttribute,/Home/Index是我的默认首页,我就是想让/home/index不走PowerAttribute.
@晓菜鸟: 想让他走什么 就在
filterContext.Result = 中赋值 不赋值表示 当前验证通过 还会继续执行下面的
这两个过虑器方法写好了,直接在需要的控制器下action下加上过虑标志就可以了。
这样是不行的,不过这个问题我解决了,谢谢回答!
@晓菜鸟: 可以的,我自己昨天写过,测试过,不要在global里面写入add方法
@背叛的冲刷: 那我这些控制器怎么应用PowerAttribute?
@晓菜鸟:
public class PowerAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { string targetUrl = "/home/index"; string loginName = CookieHelper.GetCookieValue("loginName"); if (string.IsNullOrEmpty(loginName)) { filterContext.Result = new RedirectResult(targetUrl); } base.OnActionExecuting(filterContext); }
}
这个就可以了
@背叛的冲刷: PowerAttribute不需要在任何地方引用就能行?我要的是其他的所有方法都走PowerAttribute,/home/index走NoFilterAttribute,你是不是理解错我问题的意思了?
@晓菜鸟: 哦