ASP.NET Core Razor Pages Overview
A simpler, page-focused way to build web UIs with ASP.NET Core.
Introduction to Razor Pages
Razor Pages is a page-focused programming model for ASP.NET Core that makes it easier to build dynamic, data-driven, and content-focused web UIs. It simplifies the development of page-based web applications by providing a more organized and lightweight alternative to traditional MVC patterns for certain scenarios.
Key features and benefits of Razor Pages include:
- Page-Centric Development: Each Razor Page is a self-contained unit representing a specific page in the application, with its own HTML markup and C# code-behind.
- Simplified Logic: It reduces the boilerplate code associated with controllers and views in MVC, making it easier to manage page logic.
- Clear Separation: While more integrated than MVC's controller-view split, Razor Pages still promote a good separation of concerns between UI markup and page logic.
- Model Binding and Validation: Leverages ASP.NET Core's powerful model binding and validation features.
- Dependency Injection: Seamlessly integrates with ASP.NET Core's dependency injection system.
Core Concepts
Page Models
Every Razor Page has a corresponding Page Model, which is a C# class (typically ending with .cshtml.cs
) that contains the page's logic, properties, and event handlers. The Page Model inherits from PageModel
and is decorated with the [Route]
attribute to define its URL.
Here's a simple example of a Page Model:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace MyWebApp.Pages
{
[Route("/products/{id:int}")] // Example route
public class ProductDetailModel : PageModel
{
[BindProperty(SupportsGet = true)]
public int Id { get; set; }
public string ProductName { get; set; }
public void OnGet()
{
// Simulate fetching product data
ProductName = $"Product #{Id}";
}
}
}
Razor Markup Pages (.cshtml)
The UI for a Razor Page is defined in a .cshtml
file. This file contains a mixture of HTML markup, Razor syntax (@
symbol), and directives. Each Razor Page's markup file is strongly typed to its corresponding Page Model.
The markup file for the ProductDetailModel
might look like this:
@page
@model ProductDetailModel
@{
ViewData["Title"] = $"Product Details: {Model.ProductName}";
}
Product Details
You are viewing details for: @Model.ProductName
Product ID: @Model.Id
Back to Products
@page
directive at the top of a .cshtml
file indicates that it's a Razor Page. It also implies @model
and @inject
.
Request Handlers
Razor Pages handle HTTP requests through methods named OnGet
, OnPost
, OnPut
, etc. These methods correspond to the HTTP verbs they handle and can optionally take parameters. The OnGet
method is commonly used to fetch data for displaying a page.
Example: Handling POST Request
To handle form submissions, you'd implement an OnPost
method in your Page Model. The [BindProperty]
attribute is crucial for binding form data to model properties.
Consider a simple contact form:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace MyWebApp.Pages
{
public class ContactModel : PageModel
{
[BindProperty]
public string Name { get; set; }
[BindProperty]
public string Email { get; set; }
[BindProperty]
public string Message { get; set; }
public void OnGet()
{
// Initialize form fields if needed
}
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page(); // Return to the current page if validation fails
}
// Process the form data (e.g., send email)
// ...
return RedirectToPage("./ContactSuccess"); // Redirect to a success page
}
}
}
And the corresponding Contact.cshtml
:
@page
@model ContactModel
@{
ViewData["Title"] = "Contact Us";
}
Contact Us
@section Scripts {
}
jquery.validate.unobtrusive.js
and jquery.validate.js
) using <partial name="_ValidationScriptsPartial" />
in your layout or page.
Directory Structure
Razor Pages typically reside in a Pages
folder at the root of your ASP.NET Core project. Each page consists of a .cshtml
file for the UI and a .cshtml.cs
file for the Page Model.
/Pages
/_ViewImports.cshtml
/_ViewStart.cshtml
/Index.cshtml
/Index.cshtml.cs
/About.cshtml
/About.cshtml.cs
/Products
/Index.cshtml
/Index.cshtml.cs
/Detail.cshtml
/Detail.cshtml.cs
/Contact.cshtml
/Contact.cshtml.cs
/ContactSuccess.cshtml
/ContactSuccess.cshtml.cs
Layouts and Shared Components
Like MVC, Razor Pages utilize layouts (_Layout.cshtml
) to define the overall structure and common elements of your application. Shared UI components can be implemented as Partial Views or Razor Components (if using Blazor). The _ViewImports.cshtml
file in the Pages
folder is used to import namespaces and directives into all Razor Pages within that folder and its subfolders.
Pages
folder. For example, Pages/About.cshtml
maps to the /About
URL. Custom routes can be defined using the [Route]
attribute on the Page Model.
When to Use Razor Pages
Razor Pages are an excellent choice for:
- Creating form-based applications.
- Building simple CRUD (Create, Read, Update, Delete) interfaces.
- Applications where page-centric logic is more natural than controller-centric logic.
- Migrating older ASP.NET Web Forms applications.
While powerful, for complex, highly interactive UIs or applications requiring significant API development alongside UIs, traditional MVC or Blazor might offer more structured patterns.