0

I'm using Razor Pages 7. My page has filtering, sorting and paging.

MyPage.cshtml.cs

public SelectList Products { get; set; }
public int Sort { get; set; }
public int Page { get; set; }
public int Filter { get; set; }

public async Task OnGetAsync(int sort, int page, int filter) {
  //...
}

MyPage.cshtml

<form method="get" asp-page="" asp-route-sort=@Model.Sort asp-route-page=@Model.Page>
  <select name="filter" asp-items=@Model.Products>
    <option selected value="0">Filter by product</option>
  </select>
  <input type="submit" value="submit" />
</form>

That correctly renders as:

<form method="get" action="/mypage?sort=10&page=3">
  ...
</form>

But when I submit the form, the get action only binds the filter argument. The sort and page arguments are not bound from the form's action.

Does RazorPages offer a way to bind those too?

(I could do it with JavaScript, but I'm hoping there's a RazorPages-native approach.)


UPDATE
I found a way, using hidden inputs. In the form:

<input type="hidden" name="sort" value=@Model.Sort />
<input type="hidden" name="page" value=0 />  <!-- reset page on filter change -->

But this is a manual approach with many magic strings. Is there a RazorPages "native" way?

lonix
  • 14,255
  • 23
  • 85
  • 176

1 Answers1

1

That correctly renders as:

<form method="get" action="/mypage?sort=10&page=3">   ... </form>

It already complied asp-route-somekey=someval to html correctly, appended the key value pairs to the query part.

But when I submit the form, the get action only binds the filter argument. The sort and page arguments are not bound from the form's action.

In fact, it's an issue related with Html5,when you submit form with GET method,query parameters of action attribute would be dropped. If you check the url,it would be "/mypage?filter=someval"

The only solution to appending query parameters you've self-answered

If you would accept add the arguments to the route part register the route of your page like:

@page "/MyPage/{key1?}/{key2?}"

The result:

enter image description here

I just tried with hard coding to reproduced the error:

@{
    var dic = new Dictionary<string, string>()
    {
        {"key1","10"},
        {"key2","2"}
    };
}


<form method="get" asp-page="/MyPage" asp-all-route-data=@dic >
  <select name="filter" >
    <option selected value="0">Filter by product</option>
     <option  value="1">item1</option>
      <option value="2">item2</option>
  </select>
  <input type="submit" value="submit"  />
</form>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Ruikai Feng
  • 6,823
  • 1
  • 2
  • 11
  • Thanks for confirming. Is there some "Razor Pages way" to make my code more friendly, and have less magic strings? Maybe some tag helpers or something? I already discovered that there is the `[HiddenInput]` attribute, which is useful. – lonix Feb 17 '23 at 07:28
  • 1
    I updated a solution whcih pass the arguements with route part,it may help if you would accept pass the value with route – Ruikai Feng Feb 17 '23 at 07:32
  • I met a routedata related case recently, so I came up with the routedata solution ,hopes could help https://stackoverflow.com/questions/75410483/what-should-i-include-in-my-asp-net-core-6-mvc-applications-program-cs/75431608#75431608 – Ruikai Feng Feb 17 '23 at 07:37
  • One more thing, if you don't mind? What does your cshtml look like? I wrote my form without `[BindProperty]`, but I see from your video that you did it differently - and I'm assuming your way is better than mine, so I'm curious... :-) – lonix Feb 17 '23 at 07:54
  • 1
    I just tried to reproduced the error with hardcoding ,[BindProperty(SupportGet="true")] attr allows you to bind the property of page model when you hit the onget method,so I don't have to write the arguements again,i just used to it – Ruikai Feng Feb 17 '23 at 08:05