Get controller name
As confirmed by @KiranChalla there is no simpler way then the one I've already implemented, except the minor suggestion to use GetSubRoutes()
var attributedRoutesData = request.GetRouteData().GetSubRoutes();
var subRouteData = attributedRoutesData.FirstOrDefault();
var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"];
var controllerName = actions[0].ControllerDescriptor.ControllerName;
Matija Grcic
AWS Certified Alexa Skill Builder – Specialty AWS Certified Solutions Architect - Associate Professional Scrum Master level I (PSM I) Microsoft Certified Solutions Developer (MCSD) Web Applications Microsoft Certified Technology Specialist (MCTS) Areas of interest C# language specification Javascript TypeScript ASP.NET MVC ASP.NET Web API Exception driven development by knowing more about your application's health than your customers do so you're not waiting around for customers to tell you about problems with your system. Customer (complaint) driven development by identifying the top things customers complain about most in your software, and fixing those things.
Updated on July 19, 2022Comments
-
Matija Grcic almost 2 years
In WebApiConfig.cs i have the following
public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); config.Services.Replace(typeof(IHttpControllerSelector), new MyApiControllerSelector(config)); //code omitted for brevity }
then in the MyApiControllerSelector.cs i want to get the controller
public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { var routeData = request.GetRouteData(); var controllerName = (string)routeData.Values["controller"]; //code omitted for brevity }
Pretty simple and it worked great but now using attribute routing i think it needs a different approach? - as i can't seem to find a simple way
I've tried
var controllerName = request.GetActionDescriptor().ControllerDescriptor.ControllerName;
which doesn't work.
Then reading the source with debugging lead me to
request.GetRouteData().Values["MS_SubRoutes"]
So now I have
string subRoutesKey = "MS_SubRoutes"; var attributedRoutesData = routeData.Values[subRoutesKey] as IEnumerable<IHttpRouteData>; var subRouteData = attributedRoutesData.FirstOrDefault(); var actions = (ReflectedHttpActionDescriptor[])subRouteData.Route.DataTokens["actions"]; var controllerName = actions[0].ControllerDescriptor.ControllerName;
which works but it has to be a simpler way?
UPDATE
@KiranChalla asked what's my use case so i'm posting the remaining code. Basically i'm parsing version media type
Accept: application/vnd.app.{resource}.v{version}+json
from request and returning a HttpControllerDescriptor depending on the version.HttpControllerDescriptor oldControllerDescriptor; if (controllers.TryGetValue(controllerName, out oldControllerDescriptor)) { var apiVersion = GetVersionFromMediaType(request); var newControllerName = String.Concat(controllerName, "V", apiVersion); HttpControllerDescriptor newControllerDescriptor; if (controllers.TryGetValue(newControllerName, out newControllerDescriptor)) { return newControllerDescriptor; } return oldControllerDescriptor; } return null;
-
Matija Grcic over 10 years@ainteger No, it's just a different approach to get the necessary data (controller name) from the pipeline.
-
BitMask777 almost 9 yearsThe suggestion of using
GetSubRoutes()
is an excellent one. It's the approach I've taken because usingMS_SubRoutes
is reliance on an undocumented string literal that could easily change without warning in the future.