在[授权(角色)]上使用枚举[标志]和按位运算符

Ale*_*lex 3 c# enums

我建立一个ASP.NET MVC应用5,并按照这个例子SO发布适用[Flags]enum:

[Flags]
public enum Role
{
    User = 1,
    Finance = 2,
    Management = 4,
    SystemAdmin = 8
}
Run Code Online (Sandbox Code Playgroud)

请注意,该[Flags]属性为我们提供了一种很好的方法来将多个值作为一个逗号分隔的字符串:

var roles = (Constants.Role.SystemAdmin | Constants.Role.Management).ToString();
// "SystemAdmin, Management"
Run Code Online (Sandbox Code Playgroud)

枚举值将[Authorize]在控制器和操作的属性中使用,例如:

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

但是,以上属性会生成此错误:

属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式

为什么我可以使用该.ToString()方法并在代码中获取枚举的CSV,但在[Authorize]属性中使用相同的语句时却不能?

Mat*_*and 6

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

属性参数必须是常量表达式

ToString()是一个方法调用,因此不能保证是常量.这就是你可以使用它的原因.

要解决这个问题,您可以继承子类Authorize并执行以下操作:

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

并且您可以这样使用:

[MyAuthorize(RoleEnum = Constants.Role.SystemAdmin | Constants.Role.Management)] 
Run Code Online (Sandbox Code Playgroud)

^不需要 ToString()