我们有这样的路由配置:
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "About",
url: "{controller}/{action}/{aboutId}",
defaults: new { controller = "Home", action = "About" }
);
routes.MapRoute(
name: "Contact",
url: "{controller}/{action}/{contactId}",
defaults: new { controller = "Home", action = "Contact" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
您会注意到有两个路由具有一个强制性额外参数。路线关于
和联系
。
在我们的应用中我们有两个 url
www.myapp.com/Home/About/2
效果很好。
但是当我们将浏览器导航到 www.myapp.com/Home/Contact/5
时,我们会遇到可怕的路由异常:
The parameters dictionary contains a null entry for parameter 'contactId' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Contact(Int32)' in 'RoutingTest.Controllers.HomeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
如果我们改变路由的顺序,让它看起来像这样:
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Contact",
url: "{controller}/{action}/{contactId}",
defaults: new { controller = "Home", action = "Contact" }
);
routes.MapRoute(
name: "About",
url: "{controller}/{action}/{aboutId}",
defaults: new { controller = "Home", action = "About" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
然后 Contact
url 有效,但 About
url 无效。
HomeController 看起来像这样:
public class HomeController : Controller {
public ActionResult Index() {
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
}
public ActionResult About(int aboutId) {
ViewBag.Message = "Your app description page.";
return View();
}
public ActionResult Contact(int contactId) {
ViewBag.Message = "Your contact page.";
return View();
}
}
这似乎暗示着无论 Controller Action 的名称如何,两个路由都不能具有相同数量的参数。如果两个 Controller 操作具有同名参数,则一切正常。我知道我可以开始做一些非常 hacky 的事情来解决这个问题,比如调用所有参数相同的名称或者给 Action 无意义的参数来改变参数的数量,但我实际上想知道幕后发生了什么。
我该如何解决这个问题?
最佳答案
问题的根源(没有双关语)不是路由不能有相同数量的参数。他们能。问题在于路由引擎将选择与传入请求匹配的第一条路由。您的路线仅在默认情况下有所不同,并且在模式匹配方面它们完全相同。因此,在每种情况下,您都应该点击 Contact
路线。
看起来您正在尝试根据操作设置不同的路线。我实际上不明白你为什么需要。
您可以使用以下效果。
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Contact",
url: "Home/Contact/{contactId}"
);
routes.MapRoute(
name: "About",
url: "Home/About/{aboutId}"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
但是。我强烈建议不要使用这种方法,因为您的“默认”路由将是 Contact 路由。这意味着(在 Razor 下)@Html.ActionLink()
和相关方法将是……错误的。
老实说,如果你真的只是使用...,它应该可以完美地工作
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
关于c# - ASP.NET 路由,其中两个 Controller 操作具有相同数量的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16160022/