Alex Alex - 3 days ago 4
C# Question

Using enum [Flags] and bitwise operator on [Authorize(Roles)]

I'm building an ASP.NET MVC 5 app, and following the example in this SO post to apply

[Flags]
to an
enum
:

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


Note that, the
[Flags]
attribute gives us a nice way to get multiple values as one, comma-separated string:

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


The enum values will be used in the
[Authorize]
attribute on controllers and actions, such as this:

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


However, the above attribute generates this error:


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


Why can I use the
.ToString()
method and get a CSV of the enums in code but not when using the same statement in the
[Authorize]
attribute?

Answer

Because attributes are metadata, they have the restriction that their initialization must be constant. As your error says:

An attribute argument must be a constant expression

ToString() is a method call and so can't be guaranteed to be constant. That's why you can use it.

To work around this, you might be able to subclass Authorize and do something like this:

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

And that you could use like this:

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

^ no need for ToString()