RandomHandle
RandomHandle

Reputation: 651

How to query ASP.NET MVC 5 application for class-level attributes

In my MVC 5 controllers, I often place a class-level custom attribute to manage user access permissions, e.g.

[RoleAuthorize("CreditSlipLog")]
public class CreditLogCreditSumController : Controller
{

I was wondering if it is possible to query the application to list the existing attributes for each controller class in my application (spread across multiple areas).

I know how to write LINQ queries, but I don't know what object to select against. In pseudo-code, I imagine something like this:

var list = (queryable list of areas, classes and their attributes)
           .Where(controller has "RoleAuthorize" custom filter)
           .Select(m=> new {
                       Area = m.Area,
                       Controller = m.ControllerName,
                       RoleAuthorizeValue = m.ControllerAttributeValue
                   }).ToList();

where, "RoleAuthorizeValue" is parameter value of [RoleAuthorize]

So an example result might look like this:

Area   | Controller                    | RoleAuthorizeValue
------------------------------------------------------------
Credit | CreditLogCreditSumController  | CreditSlipLog

Is there a single object I can query against, or is the query going to be very messy? Or is it something that is even possible? While I can do this manually, it is a very large application and still subject to change, making a manual document quickly out of sync with any changes in the application.

Upvotes: 1

Views: 333

Answers (1)

Eugene Komisarenko
Eugene Komisarenko

Reputation: 1543

You would need to use reflection for that and a query similar to below.

var controllersByAreas = Assembly.GetAssembly(typeof(CreditLogCreditSumController))
    .GetTypes()
    .Where(type => type.IsClass
                    && type.IsSubclassOf(typeof(Controller))
                    && type.GetCustomAttributes(typeof(RoleAuthorize), false).Any())
    .GroupBy(x => x.Namespace);

In addition to just searching for the attribute you may consider extracting the attribute and check for its properties. Resulting set can be then grouped and printed out.

If Areas of your controllers belong to specific namespaces you may consider grouping by Namespace property of the Type too, see updated code.

Upvotes: 2

Related Questions