1

I've managed to get a list of all controllers and their respective actions within my project. I am now attempting to create a custom attribute to be used on each action where I can set properties such as the action description Eg. "This creates a user". This seems to work fine but now the question is: How would I retrieve the custom attributes on each action?

Below gets a list of all controllers and actions. I just need to get each actions custom attribute called AccessControl

var controlleractionlist = asm.GetTypes()
    .Where(type => typeof(System.Web.Mvc.Controller).IsAssignableFrom(type))
    .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
    .Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any())
    .Select(x => new { Controller = x.DeclaringType.Name, Action = x.Name, CustomAttr = x.DeclaringType.GetCustomAttributes(typeof(AccessControl), false).Cast<AccessControl>()})
    .OrderBy(x => x.Controller).ThenBy(x => x.Action).ToList();

Example of a typical controller action

[HttpGet]
[AccessControl(Description="Creates a user")]
public ActionResult Index()
{
    return View();
}

And finally my custom attribute class

public class AccessControl : AuthorizeAttribute
{
  public string Description { get; set; }
}

Thank you

Martin Brisiak
  • 3,872
  • 12
  • 37
  • 51
Rossco
  • 3,563
  • 3
  • 24
  • 37

2 Answers2

0

Use this:

Expression<Action<YourController>> myAction = m => m.Index();
var method = ((MethodCallExpression)myAction.Body).Method;
var statusAttributes = method.GetCustomAttributes();

You can get all the costume attributes from the above statusAttributes collection.

error_handler
  • 1,191
  • 11
  • 19
  • If you want to access more attributes which are inherited from parent, pass true as a parameter in GetCustomAttributes(). – error_handler May 17 '16 at 10:28
  • I am not running this functionality within the controller itself. It is occurring in a different controller where I get a list of all controllers access the system together with their actions. Now for each action I would like to access the custom attributes. – Rossco May 17 '16 at 10:37
  • Be it when I iterating through each action or when I get the list of controllers and actions – Rossco May 17 '16 at 10:38
  • This is not right way to do it. You need to specify the controller name otherwise the reflection won't be able to identify that this action belongs to which controller. Action with same name might be in more than one controller. – error_handler May 17 '16 at 10:41
  • You can iterate through each controller and for-each controller you can access actions. So pass controllername in line Expression> myAction = m => m.Index(); – error_handler May 17 '16 at 10:42
0
var controlleractionlist = asm.GetTypes()
    .Where(type => typeof(System.Web.Mvc.Controller).IsAssignableFrom(type))
    .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
    .Where(m => m.GetCustomAttributes(typeof(AccessControl), true).Any() )
    .Select(x => new { Controller = x.DeclaringType.Name, Action = x.Name, CustomAttr = x.GetCustomAttributes(typeof(AccessControl), false).Cast<AccessControl>() })
    .OrderBy(x => x.Controller).ThenBy(x => x.Action).ToList();
Martin Brisiak
  • 3,872
  • 12
  • 37
  • 51
mdib
  • 1