为什么在控制器上下文之外获取路由值如此困难?

时间:2014-07-20 02:44:56

标签: c# asp.net asp.net-web-api routes asp.net-web-api2

我不明白这背后的交易是什么,为什么在控制器的Request内获取路由值如此容易,但在HttpContext.Current.Request几乎不可能做同样的事情}?

也许我只是不知道更好的方式而且它存在。有人可以确认这是在控制器外部获取路径数据的唯一方法吗?

实施例

[Route("{id}"), HttpGet]
public IHttpActionResult Test()
{
    // 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); // true
}

2 个答案:

答案 0 :(得分:2)

尝试以下代码获取路线数据:

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

注意:

请求 的类型为System.Net.Http.HttpRequestMessage。它是类System.Web.Http.ApiController的属性,或者您可以从eleswhere获取它。

GetRouteData 是类System.Net.Http.HttpRequestMessageExtensions中的扩展方法。

答案 1 :(得分:2)

第一部分

问题的答案 -

  

为什么在控制器的请求中获取路由值如此容易呢   几乎不可能在HttpContext.Current.Request做同样的事情?

我没有详细介绍类实现和其他方面。让我们考虑模型,视图和控制器在MVC架构中的责任。您可以看到只有Controller有责任将路径映射到视图,反之亦然。这是MVC架构中唯一需要路由的部分。因此可以很容易地理解为什么在Controller中找到路由值非常容易。

现在提供了实施细节。是的,当然MS人员已经做了大量的工作,以便在控制器内轻松访问它,只是一个简单的属性。但是如果你想在控制器之外你仍然可以拥有它,但这是一项艰苦的工作。这是相当可观的,因为除非你试图弄乱架构的抽象层,否则无论如何你都不需要控制器之外的路径。

第二部分

现在是第二个答案 -

  

有人可以确认这是在控制器外部获取路径数据的唯一方法吗?

当然还有其他方法。事实上,我自己无法理解你为什么通过这么努力工作获得路线价值?你不是在控制器中编写动作方法吗?如果是这样,为什么不将它用作参数呢? -

[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.
}