【问题标题】:Using enum [Flags] and bitwise operator on [Authorize(Roles)]在 [Authorize(Roles)] 上使用枚举 [Flags] 和按位运算符
【发布时间】:2017-06-20 22:48:51
【问题描述】:

我正在构建一个 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
{ ... }

但是,上面的属性会产生这个错误:

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

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

【问题讨论】:

  • 因为,正如错误所说,“属性参数必须是常量表达式”。这意味着您不能在属性中调用方法(如 ToString()),因为它不能保证是常量。
  • 谢谢,@MattBurland。关于如何让它发挥作用的任何想法?还是在这样的属性上使用时根本不可能?
  • 不可能使用这样的属性。您可以做的是创建一个具有RolesEnum 属性的属性,该属性的类型为Role,它的setter 会将Roles 字符串属性设置为value.ToString()。这可能行得通。
  • 再次感谢@MattBurland。介意将其放入答案中并为此获得一些赞誉吗?

标签: c# enums


【解决方案1】:

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

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

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()

【讨论】:

  • 我的控制器类出现错误error CS0246: The type or namespace name 'MyAuthorizeAttribute' could not be found
猜你喜欢
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 2022-03-30
  • 2011-01-20
  • 1970-01-01
  • 2017-02-01
  • 2011-01-28
  • 1970-01-01
相关资源
最近更新 更多