里面不能有带有动态代码的 [Authorize()]

Hos*_*ani 3 c# asp.net asp.net-core-mvc asp.net-core

我试图让授权接受角色作为枚举或智能枚举, 这样我就不必调试魔术字符串及其拼写错误

但我一直因这两个错误而陷入死胡同:

  • 属性构造函数参数“roles”的类型为“Role[]”,这不是有效的属性参数类型

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

这是我的代码:

授权角色.cs

public class AuthorizeRoles : AuthorizeAttribute
{
    public AuthorizeRoles(params Role[] roles)
    {
        string allowed = string.Join(", ", roles.ToList().Select(x => x.Name));
        Roles = allowed;
    }
}
Run Code Online (Sandbox Code Playgroud)

角色.cs

public class Role
{
    public readonly string Name;

    public enum MyEnum  // added
    {
        Admin,
        Manager
    }

    public static readonly Role Admin = new Role("Admin");
    public static readonly Role Manager = new Role("Manager");

    public Role(string name)
    {
        Name = name;
    }

    public override string ToString()
    {
        return Name;
    }
Run Code Online (Sandbox Code Playgroud)

在我的控制器中我做了这个

    [AuthorizeRoles(Role.Admin, Role.Manager)]
    [AuthorizeRoles(Role.MyEnum.Admin)] // added 
    public IActionResult Index()
    {
        return Content("hello world");
    }
Run Code Online (Sandbox Code Playgroud)

我看过这些答案,但它不起作用

Cha*_*man 5

由于 CLR 约束(属性如何存储在元数据中),属性参数只能是原始类型或这些类型(和Types)的数组。您不能Role(自定义对象)传递给属性。

枚举是有效的,但编译器无法将您的枚举 ( Role.MyEnum)转换为Role,这是构造函数AuthorizeRoles所需的类型。所以这是一个编译器错误。

您可以猜到,解决方案是创建一个构造函数,该构造函数采用 数组Role.MyEnum,如下所示:

public class AuthorizeRoles : Attribute
{
    public string Roles { get; private set; }

    public AuthorizeRoles(params Role.MyEnum[] roles)
    {
        string allowed = string.Join(", ", roles);
        Roles = allowed;
    }
}

public class Role
{
    public readonly string Name;

    public enum MyEnum
    {
        Admin,
        Manager
    }

    public Role(string name)
    {
        Name = name;
    }

    public override string ToString()
    {
        return Name;
    }
}

// ...

[AuthorizeRoles(Role.MyEnum.Admin)]
public IActionResult Index()
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)