如何修复ASP.NET MVC中的路由404?

Sti*_*ger 13 c# asp.net-mvc routing asp.net-mvc-3

我在尝试使用ASP.NET MVC 3.0进行路由时遇到问题.我声明了以下路线:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
    new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional } 
    );

    routes.MapRoute(
        "TestRoute",
        "{id}",
        new { controller = "Product", action = "Index3", id = UrlParameter.Optional }
    );

    routes.MapRoute(
        "TestRoute2",
        "{action}",
        new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}
Run Code Online (Sandbox Code Playgroud)

当我访问时:

http://localhost
Run Code Online (Sandbox Code Playgroud)

该网站工作正常,似乎在Default路线上.

当我访问时:

http://localhost/1
Run Code Online (Sandbox Code Playgroud)

我得到了404:

'/'应用程序中的服务器错误.

无法找到该资源.说明:HTTP 404.您要查找的资源(或其中一个依赖项)可能已被删除,名称已更改或暂时不可用.请查看以下网址,确保拼写正确.

请求的URL:/ 1

以下是这些路线对应的操作:

public ActionResult Index3(int? id)
{
    Product myProduct = new Product
    {
        ProductID = 1,
        Name = "Product 1 - Index 3",
        Description = "A boat for one person",
        Category = "Watersports",
        Price = 275M
    };

    Product myProduct2 = new Product
    {
        ProductID = 2,
        Name = "Product 2 - Index 3",
        Description = "A boat for one person",
        Category = "Watersports",
        Price = 275M
    };

    ViewBag.ProcessingTime = DateTime.Now.ToShortTimeString();

    if (id == 1)
        return View("index", myProduct);
    else
        return View("index", myProduct2);
}
Run Code Online (Sandbox Code Playgroud)

如何构建我的路由以便正确地命中所有三种操作方法?

Geo*_*ker 12

ASP.NET MVC Routing评估从上到下的路由.因此,如果两条路线匹配,则它击中的第一条路线(接近方法的"顶部"的路线RegisterRoutes)将优先于后续路线.

考虑到这一点,您需要做两件事来解决您的问题:

  1. 您的默认路线应位于底部.
  2. 如果路由包含相同数量的段,则需要对它们进行约束:

有什么区别:

example.com/1
Run Code Online (Sandbox Code Playgroud)

example.com/index
Run Code Online (Sandbox Code Playgroud)

对于解析器,它们包含相同数量的段,并且没有区别符,因此它将匹配列表中的第一个路径.

要解决这个问题,您应该确保使用ProductIdstake约束的路由:

routes.MapRoute(
    "TestRoute",
    "{id}",
    new { controller = "Product", action = "Index3", id = UrlParameter.Optional },
    new { id = @"\d+" } //one or more digits only, no alphabetical characters
);
Run Code Online (Sandbox Code Playgroud)

您的设置还存在其他问题,但这些是我们立刻想到的两件事.