I have a static method by name GetRole()
that return a string value.
Now I want to call that in using attribute parameters.
for example:
[Authorize(Roles = GetRole())]
public ActionResult Get()
{
}
public static string GetRole()
{
return "Admin";
}
But compiler get below error:
An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
Please help me to call a method in attributes.
The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are: One of the following types: bool , byte , char , double , float , int , long , sbyte , short , string , uint , ulong , ushort . The type object . The type System.
Attribute vs Parameter An attribute is a variable of any type that is declared directly in a class. A parameter is a variable defined by the function that receives a value when it is called. Usage. An attribute is used with classes and objects. A parameter is used with a function or a method.
Compiler error is pretty clear, you can't call any method when declaring an attribute (because its value must be known at compile-time) but you can derive your own custom attribute, derived from AuthorizeAttribute
to perform all logic you need. Isn't what we all did to localize NameAttribute
& friends before fancy long-waited localization-aware data annotations?
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 possible way, there you can put your own logic or simply update Roles
property and delegate to usual logic simply calling base.AuthorizeCore(context)
. Be aware that all your code here must be thread-safe.
If you're working with static methods and you want to keep that logic inside your controller then you can play around to accept (for example) something like this:
[DynamicAuthorize(typeof(MyView), nameof(GetRole))]
Note that you can access controller and view names from context.HttpContext.Request.RequestContext.RouteData
.
Then invoke such static method. Note that if logic is really complex and greatly vary then you may want to centralize this logic and use other MVC tools to do this.
An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.
This is a fact. There is no way around, an attribute argument must be 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 are (as the name suggests) compile time constant, so you maybe this workaround helps you.
If you want to determine a value at run-time, this won't work as the attributes are assigned at compile time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With