I have a small ASP.NET Core Razor Pages project. I'm making a simple list display page with a basic search functionality. In my model, I have 4 page handlers (2 of them are added for debug purposes):
public async Task OnGetAsync()
{
Posting = await _context.Postings
.Include(p => p.ItemDetails).Include(p => p.Owner).ToListAsync();
}
public async Task OnPostAsync()
{
Posting = await _context.Postings
.Include(p => p.ItemDetails).Include(p => p.Owner).ToListAsync();
}
public async Task<PageResult> OnGetSearchAsync(String search)
{
if (String.IsNullOrEmpty(search))
{
search = search.Trim();
Posting = await _context.Postings.Where(p => p.ItemDetails.ItemName.Contains(search)).ToListAsync();
}
return Page();
}
public async Task<PageResult> OnPostSearchAsync(String search)
{
if (!String.IsNullOrEmpty(search))
{
search = search.Trim();
Posting = await _context.Postings
.Where(p => p.ItemDetails.ItemName.Contains(search)).ToListAsync();
}
return Page();
}
When the form specifies method="post"
with asp-page-handler="search"
, the form calls the correct handler (OnPostSearchAsync(String search)
). However, when the form specifies method="get"
with asp-page-handler="search"
, the form calls the wrong handler (OnGetAsync()
). Is this intended? If so how can i call a custom handler while using the GET
method? Maybe using a custom handler isn't necessary but i think i should be able to if i choose to.
Here is the relevant code in .cshtml
file:
<div id="posting_search_bar_container">
<form method="get" asp-page-handler="search">
<input type="text" name="search" />
<input type="submit" value="Ara" />
</form>
</div>
<div id="posting_list_container">
@if (Model.Posting != null)
{
@foreach (var posting in Model.Posting)
{
<partial name="./Partials/_Posting" model="new Pages.Postings.Partials.PostingModel(posting);" />
}
}
</div>
Razor pages have handler-methods which are HTTP verbs. So to call a method from your page you need to put On followed by the http verb you want then your method name . And in your view pass the name to the asp-page-handler without the OnPost or OnGet prefix or Async suffix.
The PageModel consists of two Action Handler methods. This Handler method handles the GET calls, for this particular example it is not required and hence left empty. This Handler method handles the POST call when the Submit Button is clicked and the Form is submitted.
When a request is made for the page, the OnGetAsync method returns a list of movies to the Razor Page. On a Razor Page, OnGetAsync or OnGet is called to initialize the state of the page. In this case, OnGetAsync gets a list of movies and displays them.
In terms of why this happens, this answer should explain what's going on here. Essentially, asp-page-handler
sets up an action URL that includes ?handler=search
, which then gets trashed by the browser for GET requests.
In terms of workarounds, I see two:
Option 1 - Customise the routing
Taken straight from the docs, you can modify your page directive slightly in the .cshtml in order to customise the routing:
@page "{handler?}"
This option states that for the given page, use an extra segment for specifying the handler name, rather than setting it as a query-string parameter. That means your calls will change from e.g. /PageName?handler=handlerName
to /PageName/Handler
. The ?
in the {handler?}
expression from the code-snippet simply states that a handler name is optional and will therefore default to e.g. OnGetAsync
.
This option works because there is no longer a query-string value for the browser to trash, but yet the handler name is captured within the route itself.
Option 2 - Use a hidden input
When submitting a form using GET to a defined action URL, the browser builds up a query-string from the controls that live within the form. This gives the option for adding a new hidden input field to the form:
<form method="get">
<input type="hidden" name="handler" value="search" />
<input type="text" name="search" />
<input type="submit" value="Ara" />
</form>
Here, I've removed the asp-page-handler
and added a hidden input that will end up setting the query-string value of handler
to search
, which builds up a query-string that will match for OnGetSearchAsync
in your example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With