微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ASP.NET MVC路由-Url.Action发送查询字符串而不是路由值 路由模板路线名称可能的错误

如何解决ASP.NET MVC路由-Url.Action发送查询字符串而不是路由值 路由模板路线名称可能的错误

几天来我一直在寻找解决这个问题的方法,但是我很沮丧。

我有一个ASP.NET MVC应用程序,其中已实现了分页,排序和筛选。在第一个视图中它运行良好,然后在下一个视图中实现它时,它停止了工作。我正在遵循this指南。

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

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

现在,当我应用过滤器时,它仍然可以工作,但是在单击另一个页码后,将删除过滤器,但会得到正确的页码(在未过滤的结果集上)。调试显示,它将转到认的Index操作,而不是将应用过滤和排序的已定义路由。

区别在于,在更改之前,它发送的是以下网址:

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="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帮助程序通过其名称来引用它们。

路由模板

  • 这是一种模式,它定义了如何实现给定的动作以及如何匹配路由参数。
  • 它们被注册到RouteTable中,该路由表基本上是给定的url模式与关联的控制器的操作之间的映射。
  • 路线的顺序很重要,因为第一个匹配项获胜。

路线名称

  • 它们与网址模式匹配无关。
  • 它们仅在生成网址时使用。 ({RouteUrlCreatedAtRoute1)等)
  • 它们必须是全局唯一的(因此顺序无关紧要)。

可能的错误

  • 如果您使用相同的Template注册两条路由,那么当您对其中一条路由进行呼叫时,应用程序将在运行时抛出AmbiguousMatchException
    • 因此,其他路线也可以正常工作。
  • 如果您使用相同的Name注册两条路由,那么当您进行 any 调用时,应用程序将在运行时抛出InvalidOperationException
    • 因此,其他路线将无效。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。