Lesson 21 of 40
Web Development
Intermediate
40 min
Razor Pages Deep Dive
Build server-rendered web UIs with Razor Pages using VS 2026 scaffolding, tag helpers, and view components.
Part 1: Page Model Architecture
public class OrderDetailModel : PageModel
{
[BindProperty(SupportsGet = true)]
public int Id { get; set; }
public Order Order { get; set; }
public async Task<IActionResult> OnGetAsync()
{
Order = await _service.GetByIdAsync(Id);
return Order == null ? NotFound() : Page();
}
}
{
[BindProperty(SupportsGet = true)]
public int Id { get; set; }
public Order Order { get; set; }
public async Task<IActionResult> OnGetAsync()
{
Order = await _service.GetByIdAsync(Id);
return Order == null ? NotFound() : Page();
}
}
Part 2: Tag Helpers
Tag helpers provide HTML-friendly server logic:
<!-- Form with CSRF token automatic -->
<form method="post" asp-page="/Orders/Create">
<input asp-for="Order.CustomerName" class="form-control"/>
<span asp-validation-for="Order.CustomerName"></span>
</form>
<form method="post" asp-page="/Orders/Create">
<input asp-for="Order.CustomerName" class="form-control"/>
<span asp-validation-for="Order.CustomerName"></span>
</form>
Part 3: View Components
View components encapsulate reusable UI with logic:
public class CartSummaryViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
var count = await _cart.GetItemCountAsync();
return View(count);
}
}
{
public async Task<IViewComponentResult> InvokeAsync()
{
var count = await _cart.GetItemCountAsync();
return View(count);
}
}
Part 4: HTMX with Razor Pages
HTMX enables AJAX interactions without writing JavaScript:
<!-- Loads partial on click -->
<button hx-get="/Orders/Details?id=5"
hx-target="#order-detail">View</button>
<div id="order-detail"></div>
<button hx-get="/Orders/Details?id=5"
hx-target="#order-detail">View</button>
<div id="order-detail"></div>