C# 为什么在控制器上下文之外获取路由值如此困难?
我不明白这背后的交易是什么,为什么在控制器的C# 为什么在控制器上下文之外获取路由值如此困难?,c#,asp.net,asp.net-web-api,routes,asp.net-web-api2,C#,Asp.net,Asp.net Web Api,Routes,Asp.net Web Api2,我不明白这背后的交易是什么,为什么在控制器的Request中获取路由值如此容易,但在HttpContext.Current.Request上几乎不可能实现相同的操作 也许我只是不知道更好的方法,它是存在的。有人能确认这是从控制器外部获取路由数据的唯一方法吗 例子 请尝试以下代码以获取路线数据: var routeValues = Request.GetRouteData().Values["MS_SubRoutes"]; 注: 请求的类型是System.Net.Http.HttpRequest
Request
中获取路由值如此容易,但在HttpContext.Current.Request
上几乎不可能实现相同的操作
也许我只是不知道更好的方法,它是存在的。有人能确认这是从控制器外部获取路由数据的唯一方法吗
例子
请尝试以下代码以获取路线数据:
var routeValues = Request.GetRouteData().Values["MS_SubRoutes"];
注:
请求的类型是System.Net.Http.HttpRequestMessage
。它是类System.Web.Http.ApiController
的属性,也可以从eleswhere获取
GetRoutedData是类
System.Net.Http.HttpRequestMessageExtensions
中的一个扩展方法
问题的答案如下:
为什么在控制器的请求内获取路由值如此容易,但
几乎不可能在HttpContext.Current.Request上执行相同的操作
我不会详细介绍类实现和其他方面的所有细节。让我们考虑MVC体系结构中模型、视图和控制器的责任。您可以看到,只有控制器有责任将路线映射到视图,反之亦然。这是MVC架构中唯一需要路由的部分。所以很容易理解为什么在控制器中查找路由值如此容易
现在是实现细节。是的,当然微软的人已经做了大量的工作,使它在控制器中易于访问,只是一个简单的属性。但如果你想在控制器之外使用它,你仍然可以拥有它,但这是一项艰巨的工作。这是相当可观的,因为除非您试图弄乱架构的抽象层,否则无论如何您都不需要控制器之外的路由
第二部分:
现在是第二个答案-
有人能确认这是从控制器外部获取路由数据的唯一方法吗
当然还有其他方法。事实上,我自己也不明白为什么你要通过这么辛苦的工作来获得路线价值?您不是在控制器中编写动作方法吗?如果是这样的话,为什么不把它作为参数使用呢
[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.
}
是的,兄弟,我明白了。但如果我想把路线弄到控制器外面怎么办?然后我将只有
HttpContext.Current
可访问。我不知道其他方法,但(ihttpproutedata[])HttpContext.Current.Request.RequestContext.RouteData.Values[“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.
}