Bootstrap 5 dialogs for ASP .NET Core/C# using ChatGPT
Introduction Learn to use Bootstrap 5.3.4 modal dialogs effectively in ASP.NET Core Razor pages. This means moving modal dialogs out of a page and placing the modal code into a partial view, which accepts parameters to present a confirmation modal dialog. The second lesson is to use ChatGPT to write the bulk of the code even if a developer has the knowledge to do so. Using ChatGPT to write the bulk of the code saves time and focuses on business logic. The most important part taught is communication between frontend HTML to backend C# with little code required. ChatGPT Prompts used For asp.net core, razor pages, no controller, create a Bootstrap 5.3 modal dialog with two buttons yes and no that returns a bool to C# backend To call the modal from your Index.cshtml Razor Page and handle the result in its PageModel (Index.cshtml.cs), here's exactly how you do it — without controllers, staying fully in Razor Pages and Bootstrap 5.3, clean and traditional Create a page for ArchiveOrder – perfect, but code-used tables that are discouraged for accessibility reasons. Asked ChatGPT to use divs and the response was a perfect solution. Throughout each prompt, ChatGPT presented ways to extend each response, which was rejected to keep the code clean for learning purposes. Pages There are three Razor pages, the first with modal in the page while the second and third use a partial view. Index page The index page code used a modal written on the page. This is standard practice for many developers, which means that each time the same modal is needed for another page, a developer needs to copy and paste code to that page. If a decision is made to modify the modal a developer must make the change for each occurrence of the modal which means that there is room for mistakes. Delete Something Please Confirm Are you sure you want to continue? No Yes @if (Model.UserResponse.HasValue) { You clicked: @(Model.UserResponse.Value ? "Yes" : "No") } Backend public class IndexModel : PageModel { [BindProperty] public bool? UserResponse { get; set; } public void OnGet(bool? response) { UserResponse = response; } public IActionResult OnPostConfirm(string answer) { if (bool.TryParse(answer, out var result)) { UserResponse = result; } return RedirectToPage(new { response = UserResponse }); } } Index1 page Here a partial view is used for this page and Index2. This means the modal confirmation is in one place under Pages\Shared_ConfirmModal.cshtml The purpose, ask to delete a record from a database. Parameters Message, text to display ActionName, used in the calling code which can be used in backend code for decisions on what actions to take ItemId, can be a primary from an EF Core query or way for backend code to process actions. Bootstrap settings data-bs-backdrop: When backdrop is set to static, the modal will not close when clicking outside of it. modal-dialog-centered: vertically center the modal on the page @model (string Message, string ActionName, int ItemId) Confirmation @Model.Message No Yes Index1 frontend code Delete customer Delete Customer #42 @if (Model.UserResponse.HasValue) { Action: @Model.LastActionName Item ID: @Model.LastItemId Response: @(Model.UserResponse.Value ? "Yes" : "No") } The button targets the modal in ConfirmModal using _data-bs-target="#confirmModal". The if statement determines if the Yes or No button was clicked which is set in the backend code, OnPostConfirm. public class Index1Model : PageModel { public string ConfirmationMessage { get; set; } = "Do you want to delete this customer?"; public string ConfirmationAction { get; set; } = "DeleteCustomer"; public int ConfirmationItemId { get; set; } = 42; [BindProperty] public bool? UserResponse { get; set; } [BindProperty(SupportsGet = true)] public string LastActionName { get; set; } [BindProperty(SupportsGet = true)] public int? LastItemId { get; set; } public void OnGet(bool? response) { UserResponse

Introduction
Learn to use Bootstrap 5.3.4 modal dialogs effectively in ASP.NET Core Razor pages. This means moving modal dialogs out of a page and placing the modal code into a partial view, which accepts parameters to present a confirmation modal dialog.
The second lesson is to use ChatGPT to write the bulk of the code even if a developer has the knowledge to do so. Using ChatGPT to write the bulk of the code saves time and focuses on business logic.
The most important part taught is communication between frontend HTML to backend C# with little code required.
ChatGPT Prompts used
For asp.net core, razor pages, no controller, create a Bootstrap 5.3 modal dialog with two buttons yes and no that returns a bool to C# backend
To call the modal from your Index.cshtml Razor Page and handle the result in its PageModel (Index.cshtml.cs), here's exactly how you do it — without controllers, staying fully in Razor Pages and Bootstrap 5.3, clean and traditional
Create a page for ArchiveOrder – perfect, but code-used tables that are discouraged for accessibility reasons. Asked ChatGPT to use divs and the response was a perfect solution.
Throughout each prompt, ChatGPT presented ways to extend each response, which was rejected to keep the code clean for learning purposes.
Pages
There are three Razor pages, the first with modal in the page while the second and third use a partial view.
Index page
The index page code used a modal written on the page. This is standard practice for many developers, which means that each time the same modal is needed for another page, a developer needs to copy and paste code to that page. If a decision is made to modify the modal a developer must make the change for each occurrence of the modal which means that there is room for mistakes.
class="mx-auto p-2" style="width: 200px;">
class="modal fade"
id="confirmModal"
data-bs-backdrop="static"
tabindex="-1"
aria-labelledby="confirmModalLabel"
aria-hidden="true">
class="modal-dialog modal-dialog-centered">
class="modal-content ">
@if (Model.UserResponse.HasValue)
{
class="alert alert-info mt-3 text-center">
You clicked: @(Model.UserResponse.Value ? "Yes" : "No")
}
Backend
public class IndexModel : PageModel
{
[BindProperty]
public bool? UserResponse { get; set; }
public void OnGet(bool? response)
{
UserResponse = response;
}
public IActionResult OnPostConfirm(string answer)
{
if (bool.TryParse(answer, out var result))
{
UserResponse = result;
}
return RedirectToPage(new { response = UserResponse });
}
}
Index1 page
Here a partial view is used for this page and Index2. This means the modal confirmation is in one place under Pages\Shared_ConfirmModal.cshtml
The purpose, ask to delete a record from a database.
Parameters
- Message, text to display
- ActionName, used in the calling code which can be used in backend code for decisions on what actions to take
- ItemId, can be a primary from an EF Core query or way for backend code to process actions.
Bootstrap settings
- data-bs-backdrop: When backdrop is set to static, the modal will not close when clicking outside of it.
- modal-dialog-centered: vertically center the modal on the page
@model (string Message, string ActionName, int ItemId)
Index1 frontend code
class="text-center">Delete customer
class="mx-auto p-2" style="width: 200px;">
name="_ConfirmModal" model="(Model.ConfirmationMessage, Model.ConfirmationAction, Model.ConfirmationItemId)" />
@if (Model.UserResponse.HasValue)
{
class="alert alert-info mt-3">
Action: @Model.LastActionName
/>
Item ID: @Model.LastItemId
/>
Response: @(Model.UserResponse.Value ? "Yes" : "No")
}
The button targets the modal in ConfirmModal using _data-bs-target="#confirmModal".
The if statement determines if the Yes or No button was clicked which is set in the backend code, OnPostConfirm.
public class Index1Model : PageModel
{
public string ConfirmationMessage { get; set; } = "Do you want to delete this customer?";
public string ConfirmationAction { get; set; } = "DeleteCustomer";
public int ConfirmationItemId { get; set; } = 42;
[BindProperty]
public bool? UserResponse { get; set; }
[BindProperty(SupportsGet = true)]
public string LastActionName { get; set; }
[BindProperty(SupportsGet = true)]
public int? LastItemId { get; set; }
public void OnGet(bool? response)
{
UserResponse = response;
}
public IActionResult OnPostConfirm(string answer, string actionName, int itemId)
{
if (bool.TryParse(answer, out var result))
{
UserResponse = result;
if (result)
{
if (DataOperations.RemoveCustomer(itemId))
{
Log.Information("Customer {P1} deleted.", itemId);
}
}
else
{
Log.Information("Customer {P1} not deleted.", itemId);
}
// Save for feedback
LastActionName = actionName;
LastItemId = itemId;
}
return RedirectToPage(new
{
response = UserResponse,
lastActionName = LastActionName,
lastItemId = LastItemId
});
}
}
Index 2
Pages\Shared_ConfirmModal.cshtml is reused as used in the above page, index1. Rather than asking permission to delete data, here, the modal is used to ask if an item should be archived.
- The message changes.
- The for reason changes is now for archiving rather than delete.
- And the identifier changes.
Frontend code
class="text-center">Modal dialog
class="mx-auto p-2" style="width: 180px;">
Order ID: @Model.OrderId
class="mx-auto p-2" style="width: 200px;">
name="_ConfirmModal" model="@(ValueTuple.Create("Are you sure you want to archive this order?", "ArchiveOrder", Model.OrderId))" />
@if (Model.UserResponse.HasValue)
{
class="alert alert-secondary mt-3 text-center">
You clicked: @(Model.UserResponse.Value ? "Yes" : "No")
}
Backend code
public class Index2Model : PageModel
{
[BindProperty(SupportsGet = true)]
public int OrderId { get; set; } = 123; // Example ID
public string ConfirmationMessage { get; set; } = "Are you sure you want to archive this order?";
public string ConfirmationAction { get; set; } = "ArchiveOrder";
[BindProperty]
public bool? UserResponse { get; set; }
public void OnGet(bool? response)
{
UserResponse = response;
}
public IActionResult OnPostConfirm(string answer, string actionName, int itemId)
{
if (bool.TryParse(answer, out var result))
{
UserResponse = result;
if (result && actionName == "ArchiveOrder")
{
DataOperations.ArchiveOrder(itemId);
}
else
{
Log.Information("Order {P1} not archived.", itemId);
}
}
return RedirectToPage(new
{
response = UserResponse,
orderId = itemId
});
}
}
Resources
Bootstrap documentation for modals