MVC - 给定路由名称,我可以获取默认操作名称和控制器名称吗?

时间:2013-06-07 11:21:14

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

给定路由名称,我可以获取默认操作名称和控制器名称吗?

routes.MapRoute(
      name: "MonthlyCalendar",
      url: "FMB/Calendar/{jamaatName}/{year}/{month}",
      defaults: new { controller = "FMB", action = "MonthlyCalendar", 
         jamaatName = UrlParameter.Optional,year = UrlParameter.Optional,
         month=UrlParameter.Optional}
);

4 个答案:

答案 0 :(得分:5)

不,当然你不能只从路由名称中获取控制器和动作名称。路由映射可能如下所示:{controller}/{action}/{id}。如果您只有路线名称,那么这是唯一可以获得的。

如果另一方面你有一个完整的网址,如http://example.com/Home/Index,那么这是一个完全不同的故事。现在,您可以从RouteData获取controller = Home和action = Index。


更新:

在给定路由名称的情况下,您似乎尝试从路由配置中提取控制器和操作的默认值。这可以通过在DataTokens属性中注册时存储路径名来轻松完成:

RouteTable.Routes.MapRoute(
    "foo",
    "{controller}/{action}", 
    new { controller = "Home", action = "Index" }
).DataTokens["__RouteName"] = "foo";

然后:

var route = RouteTable.Routes.OfType<Route>().FirstOrDefault(x => 
    x.DataTokens.ContainsKey("__RouteName") && 
    (string)x.DataTokens["__RouteName"] == "foo"
);
if (route != null)
{
    var defaultController = route.Defaults["controller"];
    var defaultAction = route.Defaults["action"];
}

您需要在DataTokens中存储路由名称的原因是因为这个原因 路由实例中没有信息。


更新:

MS在某个时候添加了一个索引器到RouteCollection按名称查找,因此上面不再需要:

 ((System.Web.Routing.Route)Url.RouteCollection["MyRouteName"]).Defaults

您应该首先检查以确保它存在以避免出现空例外。

答案 1 :(得分:3)

我创建了这个扩展方法,将“active”css类添加到路由链接。如果RouteValueDictionary中未提供操作和控制器,则此方法根据路径名从路径获取默认操作和控制器。

您可以从RouteTable中的路线获取默认操作,但是您需要将返回值转换为Route而不是RouteBase

示例:

var action = (RouteTable.Routes["Default"] as Route).Defaults["action"] as string;

完整的扩展方法:

public static MvcHtmlString MenuRouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, RouteValueDictionary routeValues,
    IDictionary<string, object> htmlAttributes)
{
    string currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
    string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");

    var route = RouteTable.Routes[routeName] as Route;
    if (route != null)
    {
        routeValues = routeValues ?? new RouteValueDictionary();
        string routeAction = (routeValues["action"] as string ?? route.Defaults["action"] as string) ?? string.Empty;
        string routeController = (routeValues["controller"] as string ?? route.Defaults["controller"] as string) ?? string.Empty;

        if (routeAction.Equals(currentAction, StringComparison.OrdinalIgnoreCase) && routeController.Equals(currentController, StringComparison.OrdinalIgnoreCase))
        {
            htmlAttributes = htmlAttributes ?? new Dictionary<string, object>();
            var currentCssClass = htmlAttributes["class"] as string ?? string.Empty;
            htmlAttributes["class"] = string.Concat(currentCssClass, currentCssClass.Length > 0 ? " " : string.Empty, "active");
        }
    }

    return htmlHelper.RouteLink(linkText, routeName, routeValues, htmlAttributes);
}

答案 2 :(得分:1)

您可以通过阅读ControllerContext.RouteData来获取应该为您的请求提供服务的RouteData。 RouteData对象有Values,而Keys又有RouteCollection,您可以检查并应用于值以获取路径的所有片段。

通常,您可以遍历Route(这取决于您所在的上下文,例如ViewContext,或使用HtmlHelper对象)并提取每个项目并将其转换为Route.GetRouteData(YourHttpContextBaseHere)对象。之后调用RouteData,返回Route或null。如果它返回一个对象,则Defaults为您的请求提供服务并检查var defaults = (RouteValueDictionary) null; foreach (var routeBase in html.RouteCollection) { var route = (Route) routeBase; var routeData = route.GetRouteData(html.ViewContext.HttpContext); if (routeData != null) { defaults = route.Defaults; break; } } // Do something with defaults object 属性。

例如,假设您正在构建HTML帮助程序,并且您可以访问HtmlHelper对象。以下代码显示了您可以执行的操作:

{{1}}

答案 3 :(得分:0)

您可以查看System.Web.Routing.RouteTable.Routes。它包含系统中的所有路由。但如果未指定默认操作和控制器

,则无法找到它