Reputation: 651
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
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