Matija Grcic Matija Grcic - 11 months ago 136
ASP.NET (C#) Question

Get controller name

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;

Answer Source

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;
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download