我正在尝试从RouteConfig切换到路由属性。
我正在关注Adam Freeman的Pro ASP.NET MVC 5书,我试图转换以下代码来处理客户端的分页。
routes.MapRoute(
name: null,
url: "{controller}/Page{page}",
defaults: new { action = "Index", status = (string)null },
constraints: new { page = @"\d+" }
);
这很棒!当我转到不同的URL时,链接看起来非常好
http://localhost:65534/Client - Default page
http://localhost:65534/Client/Page2 - Second page
现在,我已经决定尝试使用Url属性,并且在涉及到“如何”这样的问题时会遇到一些问题。链接是。所有的链接都运行良好,但它是“路由重写”。我正在努力修复。
以下是我的控制器的重要部分。
[RoutePrefix("Client")]
[Route("{action=index}/{id:int?}")]
public class ClientController : Controller {
[Route("Page{page:int?}")]
public ActionResult Index(string sortOrder, string search = null, int page = 1) {
使用索引上方的属性,转到/ Client或/ Client / Page会给我一个404。
添加空白路线以捕捉默认页面
[Route("Page{page:int?}")]
[Route]
适用于/ Client和/ Client / Page3,但现在重写了URL。点击寻呼机第3页给我一个
的网址 http://localhost:65534/Client?page=3
这不是我想要的。将路由更改为
[Route("Page{page:int?}")]
[Route("{page=1:int?}")]
几乎100%工作,但/ Client的默认链接现在是
http://localhost:65534/Client/Page
所以,我现在正在寻求帮助。如何正确地将原始MapRoute转换为属性?
答案 0 :(得分:2)
只需使用:
[Route("", Order = 1)]
[Route("Page{page:int}", Order = 2)]
<强>更新强>
简单而简单地说,路由框架是愚蠢的。它不会决定哪条路线最适合,它只会找到匹配的路线并返回。如果您执行以下操作:
Url.Action("Index", "Client", new { page = 1 })
您希望生成的网址为/Client/Page1
,但由于您的路由page
基本上是可选的,因此它始终会选择该路由,并将任何不能填充的内容附加到URL作为查询字符串,即/Client?page=1
。解决此问题的唯一方法是实际命名所需的路由并使用该命名路由生成URL。例如:
[Route("", Order = 1)]
[Route("Page{page:int}", Name = "ClientWithPage", Order = 2)]
然后:
Url.RouteUrl("ClientWithPage", new { page = 1 })
然后,您将获得您期望的路线,因为您直接引用它。
更新#2
我不确定你的意思是“进入PagedList.MVC并为其添加名称属性”。它不需要对代码进行任何核心更改,因为PagedList已经支持自定义页面链接。只需将您的寻呼机代码更改为:
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfItems, page => Url.RouteUrl("ClientWithPage", new { page = page }))
您将获得所需的网址样式。属性路由可能比传统路由更挑剔,但我几乎没有把它称为无用。它比传统路由更灵活,但这种灵活性有一些成本。