How to implement X.PagedList PagedListPager using attribute routing?

1.1k Views Asked by At

Background

I'm using X.PagedList.Mvc.Core v8.1.0 in my ASP.NET Core 3.1 project.

I have an action with the following route attribute:

[Route("[controller]/{Foo1Param}/{Foo2Param}")]
public IActionResult FooAction(int page, string foo1Param, string foo2Param)

I have the following Razor for writing out the default style pager:

@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*@
@Html.PagedListPager(Model, page => Url.Action("FooAction", new { page, foo1Param = "foo1", foo2Param = "foo2" }))

Initial issue

When using the PagedListPager, the URL being constructed left the foo1Param and foo2Param as part of the query string, instead of the URL path.

I.e.

https://hostname/controller/fooaction?page=2&foo1Param=foo1&foo2Param=foo2

Instead of

https://hostname/controller/fooaction/foo1/foo2?page=2

Investigation

I found here that Url.Action does support attribute routing and I got the expected URL using both the Url.Action...

@Url.Action("FooAction", new { foo1Param = "foo1", foo2Param = "foo2" })

...as well as using the tag helper:

<a asp-action="FooAction" asp-route-foo1param="foo1" asp-route-foo2param="foo2">Foo link</a>

NOTE: The working examples above don't use the page parameter as this is specific to the PagedListPager.

As well as the above I found this article on codeproject.com which gave me something to try.

As a result of this, I added an additional route to give the full route of:

[Route("[controller]/{Foo1Param}/{Foo2Param}")]
[Route("[controller]/{Foo1Param}/{Foo2Param}/page={page:int}")]

Issue

The PagedListPager does now route to the path but the URL is in the structure:

https://hostname/controller/fooaction/foo1/foo2/page%3D2

Rather than:

https://hostname/controller/fooaction/foo1/foo2?page=2

The URL shows the equal sign encoded and I'm unable to use a ? in the route to move the page to a parameter as this gives a compile time error.

Literal sections cannot contain the '?' character

Any suggestions on how to give the required URL of the below, using the PagedListPager:

https://hostname/controller/fooaction/foo1/foo2?page=2

Edit:

I have the following configured in startup:

app.UseRouting();
app.UseEndpoints(endpoints =>
             {
                 endpoints.MapDefaultControllerRoute();
                 endpoints.MapControllers();
                endpoints.MapRazorPages();
             });
1

There are 1 best solutions below

0
Zeynel Abidin Öztürk On

I replaced page => with pagenumber =>. It worked for me. In my case, it seems that the problem was the usage of page keyword. Maybe it's interpreted as Razor Page.