C# ASP.NET MVC路由-Url。发送查询字符串的操作不是路由值

C# ASP.NET MVC路由-Url。发送查询字符串的操作不是路由值,c#,asp.net,asp.net-mvc,routes,C#,Asp.net,Asp.net Mvc,Routes,几天来,我一直在寻找解决这个问题的办法,但我一直被难住了 我有一个ASP.NETMVC应用程序,在那里我实现了分页、排序和过滤。它在第一个视图中运行良好,然后当我在下一个视图中实现它时,它停止了工作。我跟着导游走 在更改之前,如果我使用过滤器,它会发回并点击正确的操作并过滤结果。单击底部的一个页码将带我进入筛选结果集中的页面 更改后,我出现了一个错误,因为与多个路径匹配的路径发生冲突。由于这两个控制器的路由值相同,因此我认为需要将控制器名称添加为路由的第一部分 现在,当我应用一个过滤器时,它仍然

几天来,我一直在寻找解决这个问题的办法,但我一直被难住了

我有一个ASP.NETMVC应用程序,在那里我实现了分页、排序和过滤。它在第一个视图中运行良好,然后当我在下一个视图中实现它时,它停止了工作。我跟着导游走

在更改之前,如果我使用过滤器,它会发回并点击正确的操作并过滤结果。单击底部的一个页码将带我进入筛选结果集中的页面

更改后,我出现了一个错误,因为与多个路径匹配的路径发生冲突。由于这两个控制器的路由值相同,因此我认为需要将控制器名称添加为路由的第一部分

现在,当我应用一个过滤器时,它仍然有效,但单击另一个页码时,会删除过滤器,但会转到正确的页码(在未过滤的结果集中)。调试显示它将转到默认索引操作,而不是应用筛选和排序的已定义路由

不同之处在于,在更改之前,它发送了以下url:

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
如果我手动将其更改为路由值,而不是查询字符串,它将按预期工作

以下代码的相关部分

从UsersController:

    [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));
    }
路由配置(未更改):


知道它为什么发送查询字符串而不是路由值吗?

简言之:如果指定路由名称(不仅仅是路由模板),则可以通过帮助器通过名称引用它们

路由模板
  • 这是一种模式,它定义了如何达到给定的操作以及如何匹配路由参数
  • 它们被注册到RouteTable中,RouteTable基本上是给定url模式和关联控制器动作之间的映射
  • 路由的顺序很重要,因为第一个匹配项获胜
路线名称
  • 它们与Url模式匹配无关
  • 它们仅在Url生成期间使用。(
    RouteUrl
    CreatedAtRoute
    ()等)
  • 它们必须是全局唯一的(因此排序并不重要)
可能的错误
  • 如果您使用相同的
    模板注册了两条路由
    ,那么当您对其中一条路由进行调用时,应用程序将在运行时抛出一个
    模糊匹配异常
    • 因此,其他路线也可以很好地工作
  • 如果您使用相同的
    名称注册两条路由
    ,则当您进行任何调用时,应用程序将在运行时抛出一个
    InvalidOperationException
    • 因此,其他路线将不起作用

必须尝试为路由指定
名称(而不仅仅是
RouteAttribute
中的
模板)并使用@PeterCsala非常感谢,是的,指定名称并使用Url.RouteUrl已经修复了它。不知道为什么会这样做,我想这是因为路线相似而变得混乱。如果你给我一个答案,我会接受的。我很高兴它帮助了你。我已经发布了一个带有一些洞察力的答案。
@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 }
        );
    }

}