Why is it so hard to get route values outside controller context?

两盒软妹~` 提交于 2019-12-01 23:37:45

Part One:

The answer of the question -

Why is it so easy to get route values inside Request of controller but nearly impossible to do the same thing on HttpContext.Current.Request?

I am not going in all the details of class implementation and others. Lets just consider the responsibility of Model, View and Controller in an MVC architecture. And you can see that only the Controller has the responsibility to map routes to views and vice versa. That is the only part of the MVC architecture that needs the routes. So it can readily be understood that why it is so easy to find route values inside Controller.

Now comes the implementation details. Yeah, of course MS folks have done a great deal of work to make it easily accessible inside a controller, just a simple Property. But if you want it outside controllers you can still have it, but it is a hard work. That is considerable, cause unless you are trying to mess up the abstraction layer of the architecture, you are not gonna need the route outside the controller anyway.

Part Two:

Now comes the second answer -

Can someone confirm that this is the only way to get route data outside controller?

Of course there are other ways. In fact I myself can't understand why are you getting route values by doing so hard work? Aren't you writing your action methods in controllers? If so then why not just use it as parameter? -

[Route("{id}"), HttpGet]
public IHttpActionResult Test(int? id) //the easiest way to get route value for {id}
{
    // Simple and easy
    var route1 = Request.GetRouteData().Values["id"];

    // Wat. This is also ~6 times slower
    var routeValues = (IHttpRouteData[]) HttpContext.Current.Request.RequestContext.RouteData.Values["MS_SubRoutes"];
    var route2 = routeValues.SelectMany(x => x.Values).Where(x => x.Key == "id").Select(x => x.Value).FirstOrDefault();

    return Ok(route1 == route2 == id.Value); // true //should be true, and of course you should add null check since it is int? not int. But that is not significant here so I didn't do it.
}

Try the code below to get the route data:

var routeValues = Request.GetRouteData().Values["MS_SubRoutes"];

Note:

The type of Request is System.Net.Http.HttpRequestMessage. It is a property of class System.Web.Http.ApiController, or you can get it from eleswhere.

GetRouteData is an extension method in class System.Net.Http.HttpRequestMessageExtensions.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!