[英]ASP.NET MVC Routing - Url.Action sending query string not route values
幾天來,我一直在尋找解決這個問題的方法,但它讓我難住了。
我有一個 ASP.NET MVC 應用程序,我在其中實現了分頁、排序和過濾。 它在第一個視圖中運行良好,然后當我在下一個視圖中實現它時它停止工作。 我正在遵循本指南。
在更改之前,如果我使用過濾器,它會回傳並執行正確的操作並過濾結果。 單擊底部的頁碼之一會將我帶到過濾結果集中的頁面。
更改后,我收到一個錯誤,因為與匹配多個的路由發生沖突。 由於這兩個控制器的路由值相同,因此我認為我需要添加控制器名稱作為路由的第一部分。
現在,當我應用過濾器時,它仍然有效,但是單擊另一個頁碼會刪除過濾器,但會使用正確的頁碼(在未過濾的結果集上)。 調試告訴我它將轉到默認的索引操作,而不是將應用過濾和排序的定義路由。
不同之處在於,在更改之前,它發送了以下網址:
https://localhost:44382/Users/Index/UserName/ascending/none/all/2/an
現在它正在發送:
https://localhost:44382/Users/Index?sortKey=UserName&sortDirection=ascending&previousSortKey=none&selectedFbSupplied=all&page=2&selectedNameFilter=an
如果我手動將其更改為路由值而不是查詢字符串,它會按預期工作。
下面代碼的相關部分。
從用戶控制器:
[HttpGet]
[Route("Users/Index")]
public ActionResult Index(int? page)
{
ViewBag.SortKey = "UserName";
ViewBag.SortDirection = "ascending";
ViewBag.SelectedFbSupplied = string.IsNullOrEmpty(ViewBag.SelectedFbSupplied) ? "all" : ViewBag.SelectedFbSupplied;
ViewBag.SelectedNameFilter = string.IsNullOrEmpty(ViewBag.SelectedNameFilter) ? "" : ViewBag.SelectedNameFilter;
ViewBag.FbSupplied = new List<SelectListItem>{
new SelectListItem { Value="all", Text="All"},
new SelectListItem { Value="yes", Text="Yes"},
new SelectListItem { Value="no", Text="No"}
};
var users = SortedUserList(FilteredUsers());
int pageSize = 50;
int pageNumber = (page ?? 1);
return View(users.ToPagedList(pageNumber, pageSize));
}
[HttpGet]
[Route("Users/Index/{sortKey}/{sortDirection}/{previousSortKey}/{selectedFbSupplied}/{page:int}/{selectedNameFilter?}")]
public ActionResult Index(string sortKey, string sortDirection, string previousSortKey, string selectedFbSupplied, int? page, string selectedNameFilter="")
{
if (sortKey == previousSortKey)
{
//Key is the same, flip the direction
sortDirection = sortDirection == "ascending" ? "descending" : "ascending";
}
ViewBag.SortKey = String.IsNullOrEmpty(sortKey) ? "UserName" : sortKey;
ViewBag.SortDirection = String.IsNullOrEmpty(sortDirection) ? "ascending" : sortDirection;
ViewBag.FbSupplied = new List<SelectListItem>{
new SelectListItem { Value="all", Text="All"},
new SelectListItem { Value="yes", Text="Yes"},
new SelectListItem { Value="no", Text="No"}
};
var nameFilter = string.IsNullOrEmpty(selectedNameFilter) ? "" : selectedNameFilter;
ViewBag.SelectedFbSupplied = string.IsNullOrEmpty(selectedFbSupplied) ? "all" : selectedFbSupplied;
ViewBag.SelectedNameFilter = nameFilter;
var users = SortedUserList(FilteredUsers(nameFilter, selectedFbSupplied), sortKey, sortDirection);
int pageSize = 50;
int pageNumber = (page ?? 1);
return View(users.ToPagedList(pageNumber, pageSize));
}
以及視圖中的頁面鏈接:
@Html.PagedListPager(Model, page => Url.Action("Index", "Users" , new { sortKey = ViewBag.SortKey, sortDirection = ViewBag.SortDirection, previousSortKey = "none", selectedFbSupplied = ViewBag.SelectedFbSupplied, page = page , selectedNameFilter = ViewBag.SelectedNameFilter}))
路由配置(不變):
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
任何想法為什么它發送查詢字符串而不是路由值?
簡而言之:如果您指定路線名稱(不僅僅是路線模板),那么您可以通過RouteUrl幫助程序通過它們的名稱來引用它們。
RouteUrl
、 CreatedAtRoute
( 1 ) 等)Template
注冊兩個路由,那么當您對其中一個路由進行調用時,應用程序將在運行時拋出AmbiguousMatchException
。
Name
路由,那么當您進行任何調用時,應用程序將在運行時拋出InvalidOperationException
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.