Razor Pages in ASP.NET Core
Build dynamic, data-driven HTML UIs with Razor Pages.
What are Razor Pages?
Razor Pages is a page-based programming model for building web UIs with ASP.NET Core. It simplifies the development of page-focused scenarios compared to MVC. Each Razor Page consists of two primary components:
- Razor Page File (.cshtml): Contains HTML markup, Razor syntax for embedding server-side code, and references to a Page Model.
- Page Model (optional, .cshtml.cs): A C# class that contains the logic for the Razor Page, including event handlers, data properties, and validation logic.
This model provides a cleaner separation of concerns for web applications, particularly for scenarios where a direct page-to-logic mapping is desired.
Getting Started with Razor Pages
To create a new Razor Page project, you can use the ASP.NET Core Web App template in Visual Studio or the .NET CLI:
dotnet new webapp -o MyRazorApp
The template includes a default set of Razor Pages in the Pages
folder, such as Index.cshtml
and About.cshtml
, along with their corresponding Page Models.
Creating a New Razor Page
To add a new Razor Page:
- Create a new file named
MyNewPage.cshtml
in thePages
folder. - Add basic HTML structure:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>My New Page</title> </head> <body> <h1>Welcome to My New Page!</h1> </body> </html>
- (Optional) Create a corresponding Page Model file named
MyNewPage.cshtml.cs
in the same folder:using Microsoft.AspNetCore.Mvc.RazorPages; public class MyNewPageModel : PageModel { public string Message { get; set; } public void OnGet() { Message = "This message is from the Page Model."; } }
- Update the
.cshtml
file to reference the Page Model and display its properties:@page @model MyNewPageModel @{ ViewData["Title"] = "My New Page"; } <h1>@ViewData["Title"]</h1> <p>@Model.Message</p>
Page Model Lifecycle and Event Handlers
Razor Pages have a lifecycle managed by the ASP.NET Core framework. You can intercept specific stages of this lifecycle by implementing handler methods in your Page Model. The most common handlers are:
OnGet()
: Handles GET requests for the page.OnPost()
: Handles POST requests for the page.OnPut()
,OnDelete()
, etc.: For other HTTP verbs.
You can also define specific handlers with different names, like OnGetProducts()
or OnPostCreateUser()
. These are invoked based on the request's route data.
/MyNewPage
will execute the OnGet()
handler of MyNewPageModel
.
Example of Specific Handlers
using Microsoft.AspNetCore.Mvc.RazorPages;
public class ProductListModel : PageModel
{
public List<string> Products { get; set; }
public void OnGet()
{
Products = new List<string> { "Laptop", "Keyboard", "Mouse" };
}
public void OnGetDetails(int productId)
{
// Logic to fetch a specific product
Products = new List<string> { $"Product {productId}" };
}
}
To invoke OnGetDetails
, the URL would be something like /Products?handler=Details&productId=123
or /Products/Details/123
if configured.
Layouts and Partial Views
Razor Pages integrate seamlessly with layouts and partial views, allowing you to share common UI elements like headers, footers, and navigation menus. The default layout is typically found in Pages/Shared/_Layout.cshtml
.
You can specify a different layout for a specific page or disable the layout:
@{
Layout = "~/Pages/Shared/_CustomLayout.cshtml";
}
Or to disable the layout:
@{
Layout = null;
}
Forms and Data Submission
Submitting forms in Razor Pages is straightforward. You can use the asp-page-handler
tag helper to direct form submissions to specific handlers in your Page Model.
<form method="post">
<input asp-for="MyInput" />
<button type="submit" asp-page-handler="SubmitData">Submit</button>
</form>
In the Page Model:
public class MyFormPageModel : PageModel
{
[BindProperty]
public string MyInput { get; set; }
public void OnPostSubmitData()
{
// Process MyInput
Console.WriteLine($"Received: {MyInput}");
}
}
[BindProperty]
attribute on properties in your Page Model that you want to bind form values to.
Routing and URLs
Razor Pages uses a file-system based routing convention. The URL path typically mirrors the directory structure of the `.cshtml` files within the Pages
folder. For example:
Pages/Index.cshtml
maps to/
Pages/About.cshtml
maps to/About
Pages/Products/Index.cshtml
maps to/Products
Pages/Products/Details.cshtml
maps to/Products/Details
You can customize routing using the @page
directive with route templates or by configuring routes in Program.cs
(or Startup.cs
in older versions).
@page "{id:int}"
@model ProductDetailsModel
This would map Pages/Products/Details.cshtml
to URLs like /Products/Details/123
.