【问题标题】:Is it possible to get route data on runtime outside of controller?是否可以在控制器之外的运行时获取路由数据?
【发布时间】:2014-08-31 03:33:09
【问题描述】:

我想知道是否有可能以某种方式在控制器之外获取路由值?

这是我尝试过的。我也尝试过.Values["{projectId}"];,但我仍然得到null

[RoutePrefix("projects")]
public class UsergroupController : ApiController
{
    [Route("{projectId}/usergroups"), HttpGet]
    public IHttpActionResult Get()
    {
        // Url: /projects/123/usergroups
        // Response: null
        var projectId = HttpContext.Current.Request.RequestContext.RouteData.Values["projectId"];
        return Ok(projectId);
    }
}

我发现它的位置,但是在一个很奇怪的地方。也许可能有某种 LINQ 查询来获取它?

RouteData-Values-Values-0-0-Values-0

【问题讨论】:

  • 我认为 ASP.Net MVC 和 WebAPI 不共享所有路由信息...通过在调试器中检查 RouteData.Values 应该相对容易看到问题。
  • @AlexeiLevenkov 好点,我发现它实际上位于某个地方,但问题是 - 我如何到达那里?
  • 根据图片,您需要检查外部Keys 的值是多少(对我来说也很惊讶......而且我更惊讶的是你能够看到值 - 我预计WebAPI 有单独的路由)

标签: c# asp.net asp.net-mvc asp.net-mvc-routing


【解决方案1】:

请注意,此修复中使用的密钥不正确,“当前”在 .net 4.5 中的密钥是 MS_DirectRouteMatches

routeData.Values["MS_SubRoutes"] 应该是 routeData.Values["MS_DirectRouteMatches"])。

【讨论】:

    【解决方案2】:

    WebApi 有自己的嵌套 RouteData,这是因为它不使用 System.Web 中的 RouteData 类,而是使用自己的 HttpRouteData 类。

    WebApi 路由在 MS_SubRoutes 键下添加了一个条目,WebApi 将其用于其内部路由。

    我编写了一个扩展方法,它将 WebApi 路由数据扁平化为一个 string/object 字典,这就是您在 RouteData.Values 中可能看到的内容

    WebApiExtensions.cs

    public static class WebApiExtensions
    {
        public static IDictionary<string, object> GetWebApiRouteData(this RouteData routeData)
        {
            if (!routeData.Values.ContainsKey("MS_SubRoutes"))
                return new Dictionary<string,object>();
    
            return ((IHttpRouteData[])routeData.Values["MS_SubRoutes"]).SelectMany(x => x.Values).ToDictionary(x => x.Key, y => y.Value);
        }
    }
    

    用法:

    [RoutePrefix("projects")]
    public class UsergroupController : ApiController
    {
        [Route("{projectId}/usergroups"), HttpGet]
        public IHttpActionResult Get()
        {
            // Url: /projects/123/usergroups
            // Response: null
            object value = null;
    
            var webApiRouteData = HttpContext.Current.Request.RequestContext.RouteData.GetWebApiRouteData();
            value = webApiRouteData["projectId"];
    
            return Ok(value);
        }
    }
    

    【讨论】:

    • 这对我有用!但是,由于某种原因,我得到了两个不同的 HttpRouteData 元素和重复的路线。因此,当使用SelectMany() 展平时,它会在ToDictionary() 调用中失败,因为有重复的键。 Distinct() 会很快解决这个问题,尽管它可能不够优雅。
    猜你喜欢
    • 1970-01-01
    • 2016-10-21
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    相关资源
    最近更新 更多