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

后端 未结 2 1360
挽巷
挽巷 2021-01-21 20:18

I don\'t understand what\'s the deal behind this, why is it so easy to get route values inside Request of controller but nearly impossible to do the same thing on <

相关标签:
2条回答
  • 2021-01-21 20:48

    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.

    0 讨论(0)
  • 2021-01-21 21:00

    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.
    }
    
    0 讨论(0)
提交回复
热议问题