dncuug / X.PagedList

Library for easily paging through any IEnumerable/IQueryable in ASP.NET
https://nuget.org/packages/X.PagedList
MIT License
886 stars 213 forks source link

Html.PagedListPager doesn't appear to respect route attributes #238

Closed neilmulhy closed 1 year ago

neilmulhy commented 1 year ago

Describe the bug When I have a route attribute that contains a parameter (i.e. [Route("/foopath/{fooGuid}/foosubpath/foo")]), the route isn't getting picked up by Html.PagedListPager in the pager links, which results in an invalid URL structure for my application.

Url.Action on its own, however, does pick up the route attribute, providing the correct URL structure.

To Reproduce Steps to reproduce the behavior: 1) Create an attribute route on a controller action as below:

[Route("/foopath/{fooGuid}/foosubpath/foo")]
public IActionResult Foo(Guid fooGuid, int page = 1, int numPerPage = 10) {
///code in here to build a view model with an IPagedList<T>
///Turn the IQueryable to an IPagedList using .ToPagedList(page, numPerPage)
///And pass the view model over to the view
}

2) Enter the following as the pager partial:

@using X.PagedList; @*import this so we can cast our list to IPagedList (only necessary because ViewBag is dynamic)*@
@model IPagedList
@using X.PagedList.Mvc.Core; @*import this so we get our HTML Helper*@
<div class="pull-right">
    a) @Html.PagedListPager(Model, page => Url.Action("foo", new { fooGuid = ViewData["FooGuid"], page, numItemsPerPage = ViewData["NumItemsPerPage"]}))
    b) @Url.Action("foo", new { fooGuid = ViewData["FooGuid"], numItemsPerPage = ViewData["NumItemsPerPage"]})

</div>

3) Notice how the links generated by Html.PagedListPager don't respect the route attribute but Url.Action does: a) The page links generated are in the unexpected format - /foocontroller/foo?fooGuid=d9e2668c-9e47-4a78-8ef2-97de2c7ca6bd&page=2&numItemsPerPage=10 b) However, Url.Action gives me the expected URL - /foopath/d9e2668c-9e47-4a78-8ef2-97de2c7ca6bd/foosubpath/foo?numItemsPerPage=10

Useful Screenshot image

NOTE: The URL at the bottom of the image is what is displayed when I hover over the page 2 link in the pager.

Expected behavior I'd expect using Html.PagedListPager would work in the same way Url.Action does but with the additional page parameter.

Desktop (please complete the following information):

Additional Context I'm using version 8.4.7 of X.PagedList.

Also, I'm using the following route config in startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapControllers();
                endpoints.MapRazorPages();
            });
}

Question Are you able to offer me a workaround for this issue or is there something further I can do to get this working?

neilmulhy commented 1 year ago

Any response / workaround for me on the above please?

neilmulhy commented 1 year ago

I've found the reason why this didn't work, it was because my route didn't include the page parameter.

[Route("/foopath/{fooGuid}/foosubpath/foo")]
[Route("/foopath/{fooGuid}/foosubpath/foo/{page:int}")] //allow the PagedListPager to find this route.

Once I added this in, the Html.PagedListPager work as expected.

The PagedListPager does respect route attributes.