【问题标题】:Get a RouteTemplate by Route Name in MVC Razor View在 MVC Razor 视图中按路由名称获取 RouteTemplate
【发布时间】:2015-05-04 19:05:09
【问题描述】:

我想生成一个我的 JavaScript 在进行 AJAX 调用时可以引用的路由对象。

我在 MVC 5.2.2 中使用 AttributeRouting。

例如,我有一个Controller,其属性如下:

[RoutePrefix("api/v1/my-controller")]
public class MyController : ApiController {
    [Route(Name = "MyController.GetSomeString")]
    [HttpGet]
    public string GetSomeString()
    {
        return "Hello World!";
    }
}

然后在我的 Razor 视图中,我有以下内容:

var routes = {
    'MyController.GetSomeString': '@(Url.HttpRouteUrl("MyController.GetSomeString", new {})'
};

这会产生以下内容:

var routes = {
    'MyController.GetSomeString': '/api/v1/my-controller'
};

没关系,但现在我想要一个到带有参数的操作的路由,但还没有路由数据的值。例如,考虑来自同一控制器的以下控制器操作:

[Route("{id}/special", Name = "MyController.GetSpecialString")]
[HttpGet]
public string GetSpecialString(string id)
{
    return String.Format("Special string with id {0}.", id);
}

我想生成这个带有标记的字符串。我称它为 RouteTemplate。我发现无法检索此值:

/api/v1/my-controller/{id}/special

如果我用空路由值调用HttpRouteUrl,那么我将得到一个空字符串,而不是 RouteTemplate。

我不想为{id} 提供值。这很简单。相反,我希望在输出字符串中使用 {id} 标记。

这可能吗?如果是这样,我该如何完成?

【问题讨论】:

    标签: asp.net-mvc razor asp.net-mvc-5 asp.net-mvc-routing


    【解决方案1】:

    您应该可以通过以下方式在您的控制器中获取它:

    var url = ((System.Web.Routing.Route)this.ControllerContext.RouteData.Route).Url;
    

    立即窗口

    ?网址; “{controller}/{action}/{id}”

    然后,如果您将其放入 ViewBag 或您的模型等中,您可以在您的视图中拾取它。

    编辑:

    如果您想访问所有路线,那么它就是:

    var routeUrls = new List<string>();
    foreach (var r in RouteTable.Routes)
    {
       routeUrls.Add(((Route)r).Url);
    }
    

    如果您想按 RouteName 进行过滤,那么根据 Phil Haacks 关于此 Getting the route name for a route 的帖子,您“不能”。

    无法获取路由的路由名称,因为名称 不是路由的属性。将路线添加到 RouteCollection,名称用作内部唯一索引 路线,以便查找路线非常快。这个指数是 从未暴露。

    Phil Haack,作为 Phil Haack,随后继续展示了如何做到这一点,但需要注意的是,如果您将相同的路由添加到多个集合,这将失败。

    您创建了一些扩展方法,以便您轻松地将路由名称添加到路由数据令牌属性:

    public static Route Map(this RouteCollection routes, string name, 
        string url) {
      return routes.Map(name, url, null, null, null);
    }
    
    public static Route Map(this RouteCollection routes, string name, 
        string url, object defaults) {
      return routes.Map(name, url, defaults, null, null);
    }
    
    public static Route Map(this RouteCollection routes, string name, 
        string url, object defaults, object constraints) {
      return routes.Map(name, url, defaults, constraints, null);
    }
    
    public static Route Map(this RouteCollection routes, string name, 
        string url, object defaults, object constraints, string[] namespaces) {
      return routes.MapRoute(name, url, defaults, constraints, namespaces)
        .SetRouteName(name);
    }
    
    public static string GetRouteName(this Route route) {
        if (route == null) {
            return null;
        }
        return route.DataTokens.GetRouteName();
    }
    
    public static string GetRouteName(this RouteData routeData) {
        if (routeData == null) {
            return null;
        }
        return routeData.DataTokens.GetRouteName();
    }
    
    public static string GetRouteName(this RouteValueDictionary routeValues) {
        if (routeValues == null) {
            return null;
        }
        object routeName = null;
        routeValues.TryGetValue("__RouteName", out routeName);
        return routeName as string;
    }
    public static Route SetRouteName(this Route route, string routeName) {
        if (route == null) {
            throw new ArgumentNullException("route");
        }
        if (route.DataTokens == null) {
            route.DataTokens = new RouteValueDictionary();
        }
        route.DataTokens["__RouteName"] = routeName;
        return route;
    }
    

    然后您只需从 Route 中提取路由名称:

    var route = routes.Map("rName", "url");
    route.GetRouteName();
    

    然后你可以这样做:

    Route ajaxRoute = routes.FirstOrDefault(r => ((Route) r).GetRouteName() == "myName"));
    

    【讨论】:

    • 我想获取所有路由的模板,而不仅仅是当前控制器操作的路由。我尝试循环遍历RouteTable.Routes,但它们是内部类型RouteCollectionRouteRouteBase,无论如何似乎都无法访问这种类型的东西。
    猜你喜欢
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 2016-06-15
    • 2020-06-29
    相关资源
    最近更新 更多