c# - ASP.NET 路由,其中​​两个 Controller 操作具有相同数量的参数

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

我们有这样的路由配置:

  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/

相关文章:

asp.net-mvc - 在 MVC4.0 中使用分页实现类别/子类别的更好选择是什么?

jquery - 从我的服务器发送的静态内容(例如 : . css、.js)是否被 gzip 压缩?

c# - 为什么这个 webapi2 属性路由不起作用?

javascript - MVC Controller 从具有数据的 JavaScript 对象传入 null

c# - MVC4 : same url base for different actions

c# - 如何 `extern alias` 一个带有.Net核心的程序集?

c# - 用C#发送邮件

c# - app.config 的自定义配置 - 部分集合?

javascript - 在 DOM 中构建全局变量

c# - 升级到WebApi.Core报错-直接路由不能使用参数 'controller'