Razor Pages, form page handler not working with GET method
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.
user3402183
Updated on June 23, 2022Comments
-
user3402183 almost 2 years
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"
withasp-page-handler="search"
, the form calls the correct handler (OnPostSearchAsync(String search)
). However, when the form specifiesmethod="get"
withasp-page-handler="search"
, the form calls the wrong handler (OnGetAsync()
). Is this intended? If so how can i call a custom handler while using theGET
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>