5

我有一个 ASP.Net 应用程序,它有一个名为“客户”的区域。这个区域有一个同名的控制器,带有一个名为 Index 的方法。

我定义了以下路线:

context.MapRoute(null,
    "Customers/{controller}/{action}",
    new { controller = "customers", action = "Index" }
);

这允许我导航以使用以下 URL 导航到我的客户控制器上的 index 方法。

我的域/客户

在我的客户区,我还有另一个控制器,称为产品。这有许多方法可以让我使用产品实体(目前主要由 Visual Studio 自动生成)。

使用我当前的路线,我可以使用如下 URL 导航到产品控制器:

MyDomain/Customers/Products(显示产品控制器的索引页面) MyDomain/Customers/Products/Create(显示添加新产品的页面)。MyDomain/Customers/Products/Details?id=1234(显示 id 为 1234 的产品)

现在我想要做的是导航到具有更加用户友好的 URL 的详细信息页面,例如:

我的域/客户/产品/1234

我定义了一条如下所示的新路线:

context.MapRoute(null,
    "Customers/Products/{id}",
    new { controller = "Products", action = "Details" }
    );

该路线是在我演示的第一条路线之前定义的。这使我可以根据需要导航到产品页面,但是我无法再导航到产品控制器上的其他方法。

EG 以下网址

我的域/客户/产品/创建

给我以下错误:

参数字典包含方法“System.Web.Mvc.ViewResult Details(Int32)”的不可空类型“System.Int32”的参数“id”的空条目

如果我更改路由的顺序,那么我可以导航到产品控制器上的所有方法,但我的详细信息 URL 会恢复为具有查询参数的旧格式。

如果我将路线更新为如下所示:

context.MapRoute(null,
    "Customers/Products/{id}",
    new { controller = "Products", action = "Details", id = UrlParameter.Optional }
    );

然后我仍然遇到同样的问题。

谁能告诉我如何构建我的路线以获得我想要的结果?总之:

  1. 如果我导航到客户区域,我希望我的 URL 看起来像“MyDomain/Customers”
  2. 如果我导航到产品详细信息页面,我希望我的 URL 看起来像“MyDomain/Customers/Products/1234”。
  3. 如果我导航到任何其他产品页面,我希望我的 URL 看起来像“MyDomain/Customers/Products/Create”
4

4 回答 4

4

如果 ID 始终是 int,那么您可以向路由添加约束,如下所示:

context.MapRoute(null,
                 "Customers/Products/{id}",
                 new {controller = "Products", action = "Details", id = UrlParameter.Optional},
                 new {id = @"\d+"} // Constraint to only allow numbers
                );
于 2012-08-22T10:04:42.233 回答
1

尝试这样的事情:

public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
        "Products_Details",
        "Customers/Products/{id}",
        new { controller="Products", action="Details" },
        new { id = @"\d+" }
    );

    context.MapRoute(
        "Customers_default",
        "Customers/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}

更新:增加了对路线的约束。

说明:第一个路由映射到您的详细信息页面,并强制用户提供具有数字格式的 id(第一个参数中的最后一个参数MapRoute)。如果 id 没有格式\d+,它将与路由不匹配,将使用默认值。这将为您提供以下路线:

Customers\Products (index)
Customers\Products\1234 (details of 1234)
Customers\Products\Create (create page for products)
Customers\Products\Edit\1234 (edit page for 1234)
于 2012-08-22T10:12:33.943 回答
0

如果您想保留现有路线,请尝试执行以下操作:

context.MapRoute(null,
     "Customers/Products/{id}", // id is optional, so Customers/Products might reasonably return all products
     new { controller = "Products", action = "Details", id = UrlParameter.Optional },
     new {id = @"\d+"} // must be numeric if present
);

context.MapRoute(null,
     "Customers/Products/{action}/{id}", // Id is optional, so this needs an action.
     new { controller = "Products", action = "Details", id = UrlParameter.Optional }
     // maybe the id is not numeric for all actions? I don't know so I won't constrain it.
);

context.MapRoute(null,
     "Customers/{controller}/{action}", // Default Customers route
     new { controller = "customers", action = "Index" }
);

前两个处理一个 URL,就像/Customers/Products/...一个或两个其他部分一样,最后一个处理其他任何以开头的部分/Customers/

于 2012-08-22T10:12:38.720 回答
0

试试这个

    context.MapRoute(
                    "Customers_Products",
                    "Customers/Products/{productId}",
                    new { controller = "Products", action = "Details", productId= UrlParameter.Optional }
                );

    context.MapRoute(null,
                    "Customers/{controller}/{action}",
                     new { controller = "customers", action = "Index" }
);
于 2012-08-22T10:20:44.060 回答