ActionLink/RouteLink 没有使用指定的 actionName

ActionLink/RouteLink not using specified actionName

Index.cshtmlEuroController 视图中,我有一个 ActionLink我想使用欧元控制器的 "IndexByYear" 动作:

@Html.ActionLink("Year 2006", "IndexByYear","Euro", new { id = "", year = 2006 }, null)

但问题是它转到了 Index() 方法,即使它是在 RouteConfig 上设置的所有内容:

routes.MapRoute(
     name: "Default",
     url: "{controller}/{id}",
     defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
     );
routes.MapRoute(
     name: "Euro",
     url: "{controller}/{year}/{id}",
     defaults: new { controller = "Euro", action = "IndexByYear", year = DateTime.Now.Year, id = UrlParameter.Optional }
     );

这是 EuroController:

    public ActionResult Index(int? id)
    {
     ...
    }
    public ActionResult IndexByYear(int? id, int year)
    {
     ...
    }

这也不起作用,因为它也转到 Index() 方法:

@Html.RouteLink("Ano 2006","Euro",new { id = "", year = 2006 },null)

如果我手动导航到 domain/Euro/2016/1,那么它会使用正确的路线。似乎没有参数,它通过默认路由。

我的问题是,为什么 ActionLink 不使用指定的 IndexByYear,或者 RouteLink 使用指定的默认(欧元)路由?

如果你想要只是 EuroController 有一个"special" 路由,你会想要做这样的事情:

routes.MapRoute(
     name: "Euro",
     url: "euro/{year}/{id}",
     defaults: new { controller = "Euro", action = "IndexByYear", year = DateTime.Now.Year, id = UrlParameter.Optional }
     );

routes.MapRoute(
    name: "DefaultNoController",
    url: "{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    constraints: new { isMethodInHomeController = new RootRouteConstraint<Controllers.HomeController>() }
    );

routes.MapRoute(
     name: "Default",
     url: "{controller}/{action}/{id}",
     defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
     );

约束的定义如下:

public class RootRouteConstraint<T> : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        var rootMethodNames = typeof(T).GetMethods().Select(x => x.Name.ToLower());
        return rootMethodNames.Contains(values["action"].ToString().ToLower());
    }
}

这将匹配

  • domain/euro/1 到 EuroController 上的索引操作
  • domain/euro/2008/1 到 EuroController 上的 IndexByYear 操作
  • domain/ 到 HomeController 上的索引操作
  • domain/about 到 HomeController 上的“关于”操作
  • domain/someothercontroller 到您定义的任何其他控制器上的 Index 操作

您可能想阅读 https://msdn.microsoft.com/en-us/library/cc668201.aspx and https://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/creating-a-custom-route-constraint-cs