I have a .cshtml page that displays some information about a racing session. At the bottom I want to add a button that invokes a function getting drivers of that session to the database and redirects me to a page displaying them in a list.
My code is as follows:
@page
@model WebApplication1.Pages.Sessions.DetailsModel
@{
ViewData["Title"] = "Details";
@functions {
PlatformyProgramistyczneAPI.DbManager dbman = new PlatformyProgramistyczneAPI.DbManager();
public void OnPost()
{
dbman.ReplaceDriversDbBySession(Model.SessionDb.session_key);
Response.Redirect("/Drivers");
}
}
}
<h1>@Html.DisplayFor(model => model.SessionDb.country_name)</h1>
<div>
<h4>@Html.DisplayFor(model => model.SessionDb.circuit_short_name) @Html.DisplayFor(model => model.SessionDb.year)</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
Start date
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.SessionDb.date_start)
</dd>
<dt class="col-sm-2">
End date
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.SessionDb.date_end)
</dd>
</dl>
</div>
<form asp-page-handler="post">
<button onclick="" class="btn btn-default">Show drivers</button>
</form>
I created a form at the bottom that only contains a submit button in hopes I could invoke the OnPost() function, but when I click it, all data related to the model disappears from the page and none of the operations in OnPost are performed. When I comment out every line related to the model it works as intended.
Why can't I use buttons with models in this way? What is the proper way to invoke C# on press of a button?
Here is my DetailsModel code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using PlatformyProgramistyczneAPI.F1Api;
namespace WebApplication1.Pages.Sessions
{
public class DetailsModel : PageModel
{
private readonly PlatformyProgramistyczneAPI.F1Api.DriversDatabase _context;
public DetailsModel(PlatformyProgramistyczneAPI.F1Api.DriversDatabase context)
{
_context = context;
}
public SessionDb SessionDb { get; set; } = default!;
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
var sessiondb = await _context.Sessions.FirstOrDefaultAsync(m => m.id == id);
if (sessiondb == null)
{
return NotFound();
}
else
{
SessionDb = sessiondb;
}
return Page();
}
public IActionResult OnPost(int session_key)
{
PlatformyProgramistyczneAPI.DbManager dbman = new PlatformyProgramistyczneAPI.DbManager();
dbman.ReplaceDriversDbBySession(session_key);
return Redirect("/Drivers");
}
}
}


I somehow managed to get it to work by replacing the form from the original code with this:
If anybody knows why this works and my first approach doesn't, I'd be very thankful for an explanation as I don't really get the difference between those two ways. If in general there is a better way to invoke C# code with a button I would also much appreciate any and all tips for future reference.