7

我正在尝试使用最新的 asp.net mvc 4 架构来获得一些路由约束。在 App_Start 下有一个名为 RouteConfig.cs 的文件。

如果我从下面的示例中删除约束部分,则 url 有效。但我需要添加一些约束,以便 url 不匹配所有内容。

应该工作:/videos/rating/1

不工作:/videos/2458/Text-Goes-Here

这就是我所拥有的:

//URL: /videos/rating/1
routes.MapRoute(
    name: "Videos",
    url: "videos/{Sort}/{Page}",
    defaults: new { controller = "VideoList", action = "Index", Sort = UrlParameter.Optional, Page = UrlParameter.Optional },
    constraints: new { Sort = @"[a-zA-Z]", Page = @"\d+"}
);
4

2 回答 2

12

如果你想在同一条路由上有多个可选参数,你会遇到麻烦,因为你的 url 必须始终指定第一个才能使用第二个。仅仅因为您使用约束并不能阻止它评估参数,它反而无法匹配这条路线。

以此为例:/videos/3

当它试图匹配时,它会找到视频,并说,“好的,我仍然匹配”。然后它查看下一个参数,即 Sort,它得到值 3,然后根据约束检查它。约束失败,所以它说“OPPS,我不匹配这条路线”,然后它继续前进到下一条路线。为了指定没有定义 sort 参数的页面,您应该定义 2 个路由。

//URL: /videos/rating/1
routes.MapRoute(
    name: "Videos",
    url: "videos/{Sort}/{Page}",
    defaults: new { controller = "VideoList", action = "Index", Page = UrlParameter.Optional },
    constraints: new { Sort = @"[a-zA-Z]+", Page = @"\d+"}
);

//URL: /videos/1
routes.MapRoute(
    name: "Videos",
    url: "videos/{Page}",
    defaults: new { controller = "VideoList", action = "Index", Sort = "the actual default sort value", Page = UrlParameter.Optional },
    constraints: new { Page = @"\d+"}
);

我尽可能将最具体的路线放在首位,并以最不具体​​的路线结束,但在这种情况下,由于限制,顺序应该无关紧要。我所说的具体是最定义的值,所以在这种情况下,您必须在第一个路由中定义排序,并且您还可以指定页面,因此它比仅使用页面参数的路由更具体。

于 2012-11-30T19:05:16.880 回答
1

我的输入可能相当晚,但对于仍在寻找答案的其他人。为了简单起见,我将在我的 RoutesConfig 文件中使用以下内容

 routes.MapRoute(
     name: "Videos",
     url: "{controller}/{action}/{id}",
     defaults: new { controller = "VideoList", action = "Index", id="" },
     constraints: new { id = @"\d+"}
     );

根据您选择的实现,id 可以是 UriParameter.Optional,但在这种情况下它将是 id="" ,因为我们将在运行时传递一个字符串/int。

这种风格是从http://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/creating-a-route-constraint-cs

通过约定控制器类要记住的一件事总是以控制器结尾,例如 VideoListController 类。此类应列在包含以下方法的控制器文件夹下

public ActionResult Index(string id)
{
    // note this maps to the action
    // random implementation
    ViewBag.Message=id;
    View()
}

// 请注意,这种方法仍然匹配任何字符串...要仅匹配整数,必须重写 Index 方法

public ActionResult Index(int id)
{
     // note this maps to the action
     ViewBag.Message=id;
     View()
}

因此,此方法适用于 VideoList/Index/12,但在放置 VideoList/Index/somerandomtext 时,它会在运行时引发错误。这可以通过使用错误页面来解决。我希望这有帮助。如果它非常有用,请投票。

于 2015-12-09T22:06:53.663 回答