2017-06-20 32 views
1

我建立一个ASP.NET MVC应用5,并按照本SO post的例子申请[Flags]enum上[授权(角色)]使用枚举[国旗]和位运算符

[Flags] 
public enum Role 
{ 
    User = 1, 
    Finance = 2, 
    Management = 4, 
    SystemAdmin = 8 
} 

注意的是,[Flags]属性为我们提供了一个很好的方式来获得多个值作为一个逗号分隔字符串:

var roles = (Constants.Role.SystemAdmin | Constants.Role.Management).ToString(); 
// "SystemAdmin, Management" 

枚举值将在控制器和行动,像这样的[Authorize]属性一起使用:

[Authorize(Roles = (Constants.Role.SystemAdmin | Constants.Role.Management).ToString())] 
public class SomeController : Controller 
{ ... } 

然而,上面的属性生成此错误:

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

我为什么可以使用.ToString()方法,并得到一个CSV在代码中枚举,但在[Authorize]属性用同样的语句时,不?

+1

因为,错误说*“一个属性参数必须是一个常量表达式”*。这意味着你不能在属性中调用一个方法(比如'ToString()'),因为它不能保证是常量。 –

+0

谢谢,@MattBurland。任何想法如何得到这个工作?或者当它用于像这样的属性时,它是不可能的? – Alex

+0

不可能使用这样的属性。你可以做的是创建一个属性,该属性具有'Role'类型的'RolesEnum'属性,它在setter中将'Roles'字符串属性设置为'value.ToString()'。这可能会起作用。 –

回答

4

因为属性是元数据,所以它们的限制是它们的初始化必须是常量。正如你的错误所说:

An attribute argument must be a constant expression

ToString()是一个方法调用,所以不能保证是恒定的。这就是为什么你可以使用它。

要解决这个问题,你可能能够继承Authorize,做这样的事情:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    private Role roleEnum; 
    public Role RoleEnum 
    { 
     get { return roleEnum; } 
     set { roleEnum = value; base.Roles = value.ToString(); } 
    } 
} 

而且,你可以使用这样的:

[MyAuthorize(RoleEnum = Constants.Role.SystemAdmin | Constants.Role.Management)] 

^不需要ToString()