Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to plug method parameters into custom attribute

I have a custom Attribute called AuthoriseAttribute whose constructor looks like this:

public AuthoriseAttribute(int userId)
{
  .. blah
}

This is used with a method called GetUserDetails() like this:

[Authorise(????????)]
public UserDetailsDto GetUserDetails(int userId)
{
  .. blah
}

At runtime, the presence of the Authorise attribute causes some authorisation code to execute which requires the ID of the user. Obviously, this can be extracted from the parameter of the GetUserDetails() method, but this means that the authorisation code depends on the method's parameter being given a particular name.

I would like to be able to pass in the actual value of the userId parameter into the attribute, so that the authorisation code works with the value passed in to the attribute (i.e. not the method parameter), whose name is known.

Something like this (which doesn't work):

[Authorise(userId)]
public UserDetailsDto GetUserDetails(int userId)
{
  .. blah
}

Is such a thing possible?

like image 981
David Avatar asked May 03 '12 16:05

David


People also ask

How can you specify target for custom attribute?

Which of the following are correct ways to specify the targets for a custom attribute? A. By applying AttributeUsage to the custom attribute's class definition.

How do I add custom attributes to my framework?

AttributeUsage has a named parameter, AllowMultiple , with which you can make a custom attribute single-use or multiuse. In the following code example, a multiuse attribute is created. In the following code example, multiple attributes of the same type are applied to a class. [Author("P.

Can you add custom attributes HTML tags?

Thanks to HTML 5, we now have the ability to embed custom data attributes on all HTML elements. These new custom data attributes consist of two parts: Attribute Name. The data attribute name must be at least one character long and must be prefixed with ' data- '.


2 Answers

There is a way to do this _in ASP.NET MVC_ with action-methods (not with attributes in general)

public class CustomAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        int userId = (int)filterContext.ActionParameters["userId"];
    }
}
like image 117
Alex from Jitbit Avatar answered Oct 16 '22 21:10

Alex from Jitbit


Making vcsjones' comment an answer, this is not possible.

Attributes are metadata; they are compiled into the assembly at compile-time and do not change during runtime. As such, any parameters you pass into an attribute must be constants; literals, constant variables, compiler defines, etc.

The one way this would work is to make the attribute an AOP element, using a framework like PostSharp or rolling your own with the Unity Framework etc. This would allow you to attach an "interceptor" to the method by decorating it with an attribute, which will then run code in the attribute and will also have knowledge about exactly how the method was called including parameter values. Check out this blog: http://www.progware.org/Blog/post/Interception-and-Interceptors-in-C-(Aspect-oriented-programming).aspx

like image 44
KeithS Avatar answered Oct 16 '22 20:10

KeithS