ActionLink/RouteLink 没有使用指定的 actionName
ActionLink/RouteLink not using specified actionName
在 Index.cshtml 的 EuroController 视图中,我有一个 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
在 Index.cshtml 的 EuroController 视图中,我有一个 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