2011-11-03 126 views
7

我有一个简单的ASP.Net MVC 3应用程序,它有一些控制器和很少的操作。ASP.Net MVC 3:反向授权属性

现在,由于这是基于用户的应用程序,因此大多数控制器操作都需要用户进行身份验证。 MVC使用内置的Authorize属性处理这个问题,您可以使用它来单独装饰控制器和/或操作。

伟大的事情是,你可以仅应用于控制器和给定控制器的所有行动将已存入过的属性 - 大量的打字保存;)

但我有一个控制器,可以说, 10次​​行动。但是我希望其中一个操作没有应用Authorize属性。

是的,我可以将该属性应用于其他9并将其从控制器中删除,这将完全符合我的需要。但是有没有办法将它应用到控制器,并选择排除其中一个操作?

实际上,如果有想有点像......

[!Authorize][NotAuthorize]

我知道我可以创建一个自定义一个会做的工作,但我想知道的是内置 - 在这种方式?还是必须将该属性应用于所有其他9个动作?

回答

2

菲尔哈克写了一篇博客文章最近处理这个确切的情况:

Conditional Filters in ASP.NET MVC 3

他的解决方案包括编写自定义“条件筛选供应商”,它允许一个指定过滤条件到一个动作的属性方法。

细节和推理在他的文章中,但代码相对简单。首先,创建过滤器供应商:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Mvc; 

public class ConditionalFilterProvider : IFilterProvider { 
    private readonly 
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> _conditions; 

    public ConditionalFilterProvider(
    IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions) 
    { 

     _conditions = conditions; 
    } 

    public IEnumerable<Filter> GetFilters(
     ControllerContext controllerContext, 
     ActionDescriptor actionDescriptor) { 
    return from condition in _conditions 
      select condition(controllerContext, actionDescriptor) into filter 
      where filter != null 
      select new Filter(filter, FilterScope.Global, null); 
    } 
} 

,然后应用它:

IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions = 
    new Func<ControllerContext, ActionDescriptor, object>[] { 

    (c, a) => c.Controller.GetType() != typeof(HomeController) ? 
     new MyFilter() : null, 
    (c, a) => a.ActionName.StartsWith("About") ? new SomeFilter() : null 
}; 

var provider = new ConditionalFilterProvider(conditions); 
FilterProviders.Providers.Add(provider); 
10

需要注意的是一个新的属性已在ASP.NET MVC中添加4.0这正是这么做的:
[AllowAnonymous]