How to call a method when using attribute parameters

I have a static method called GetRole() that returns a string value.
Now I want to call it when using attribute parameters.
eg:

 [Authorize(Roles = GetRole())] public ActionResult Get() { } public static string GetRole() { return "Admin"; } 

But the compiler gets below the error:

The attribute argument must be a constant expression, a typeof expression, or an array creation expression type attribute attribute

Please help me call the method in the attributes.

+7
methods c # attributes
source share
4 answers

The compiler error is quite understandable, you cannot call any method when declaring an attribute (because its value must be known at compile time), but you can get your own custom attribute obtained from AuthorizeAttribute to execute all the necessary logic. Isn't that what we all did to localize NameAttribute and friends before imagining the long-awaited annotations of localization data?

Proof of concept:

 class DynamicAuthorizeAttribute : AuthorizeAttribute { protected bool AuthorizeCore(HttpContextBase context) { // Perform your logic here, eventually update Roles property } } 

And then:

 [DynamicAuthorize] public ActionResult Get() { // ... } 

This is just one of the possible ways: you can put your own logic, or simply update the Roles property and delegate it to the usual logic, simply by calling base.AuthorizeCore(context) . Keep in mind that all of your code here should be thread safe.

If you work with static methods and want to keep this logic inside your controller, you can play to take (for example) something like this:

 [DynamicAuthorize(typeof(MyView), nameof(GetRole))] 

Please note that you can access the controller and view the names from context.HttpContext.Request.RequestContext.RouteData .

Then call such a static method. Note: if the logic is really complex and changing a lot, you might want to centralize this logic and use other MVC tools to do this.

+5
source share

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

It is a fact. There is no way, the attribute argument must be a compile-time constant. You cannot call a method.

What you can do is define a constant:

 public class MyClass { public const string Role = "Admin"; [Authorize(Roles = Role)] public ActionResult Get() { } } 

Constants (as the name implies) determine the compile-time constant, so you might be able to get around this solution.

If you want to determine the value at run time, this will not work, since attributes are assigned at compile time.

+1
source share

I used my own registered user authorization method.

Look, maybe this will help you.

  public static bool GetRole(string Codename) { if (LogInUser == null) { return false; } return true; } 

and check if the user has access or not,

 if (!Utility.GetRole("Admin")) return View("AccessDenied"); 

I also have code for standard built-in authorization,

if you need it, just comment below.

0
source share

You can do it,

this method is better because here you can pass a list of roles that should be authorized, instead of a single role. (Look below, I went through the administrator and master of both)

 [Authorization(Roles = "admin,master")] public class MyController : Controller { //Your remaining code. } 

and authorize it, I have this method.

 public class Authorization : AuthorizeAttribute { public string Roles { get; set; } protected override bool AuthorizeCore(HttpContextBase httpContext) { if (User != null) { if (String.IsNullOrEmpty(Roles)) { return true; } string[] split = Roles.Split(','); foreach (UserRole item in User) { if (split.Contains(item.Role.CodeName)) { return true; } } return false; } else return false; } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { filterContext.Result = new HttpUnauthorizedResult(); } } 
0
source share

All Articles