Razor Pages
Razor Pages is a page-focused programming model for building web UI with ASP.NET Core. It makes it easier to build cohesive sets of Razor files—including Razor markup, C#, and other code—that work together to present data. Razor Pages is built on top of MVC and is recommended for scenarios where you are building page-centric application functionality.
It simplifies the development of Razor-based web applications by providing a cleaner separation between concerns and a more intuitive structure compared to traditional MVC controllers and views, especially for scenarios involving many distinct pages.
Razor Syntax
Razor is a templating engine used for creating dynamic web pages. It allows you to embed server-side C# code within HTML using a special syntax:
@
symbol is used to transition from HTML to C# code.@variableName
displays the value of a variable.@{ ... }
block for multiple C# statements.@if
,@foreach
,@using
, etc., for control flow.
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Current time on server: @DateTime.Now</p>
</div>
Page Model
Each Razor Page is typically associated with a "Page Model" class, which inherits from PageModel
. This class handles the logic for the page, such as retrieving data, processing form submissions, and exposing properties and methods to the Razor markup.
// Pages/Index.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
public class IndexModel : PageModel
{
public string Message { get; set; }
public void OnGet()
{
Message = "Hello from the Page Model!";
}
}
The Razor file (Index.cshtml
) uses the @page
directive and the @model
directive to link to its Page Model:
@page
@model IndexModel
@{
ViewData["Title"] = "Index Page";
}
<h1>@Model.Message</h1>
<p>This is a Razor Page example.</p>
Routing
Razor Pages uses a file-based routing convention. The URL path for a Razor Page is derived from its file path relative to the Pages
folder.
Pages/Index.cshtml
maps to/
Pages/About.cshtml
maps to/About
Pages/Products/List.cshtml
maps to/Products/List
You can customize routing using the @page
directive with an explicit route template:
@page "/my-custom-url"
@model MyCustomPageModel
Layouts
Layouts allow you to define a common structure for multiple Razor Pages, such as headers, footers, and navigation bars. By default, Razor Pages uses the _Layout.cshtml
file found in the Pages/Shared
folder.
To specify a different layout or no layout, you can use the Layout
property in the Page Model or directly in the Razor file:
@{
Layout = "_AnotherLayout.cshtml";
}
Or in the Page Model's constructor or OnGet method:
public class MyPageModel : PageModel
{
public MyPageModel()
{
Layout = "_AnotherLayout.cshtml";
}
public void OnGet() { }
}
Handling Forms
Razor Pages provide an intuitive way to handle form submissions using HTTP POST methods. The Page Model's handler methods, typically named OnPost...
, are invoked when a form is submitted via POST.
Example Form:
// Pages/Contact.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
public class ContactModel : PageModel
{
[BindProperty]
public string UserName { get; set; }
public string ResultMessage { get; set; }
public void OnGet() { }
public IActionResult OnPost()
{
if (!string.IsNullOrEmpty(UserName))
{
ResultMessage = $"Hello, {UserName}!";
}
else
{
ResultMessage = "Please enter your name.";
}
return Page(); // Renders the current page again
}
}
The [BindProperty]
attribute automatically binds form values to properties of the Page Model.
Data Binding
[BindProperty]
is a powerful attribute for data binding. It can be used to bind form data, route data, and query string parameters to Page Model properties. When used with POST requests, it's commonly used to bind form inputs.
Validation
ASP.NET Core's built-in validation attributes can be applied to Page Model properties. These attributes can then be leveraged for both server-side and client-side validation.
using System.ComponentModel.DataAnnotations;
public class ProductModel : PageModel
{
[Required]
[StringLength(50, ErrorMessage = "Name cannot be longer than 50 characters.")]
[BindProperty]
public string Name { get; set; }
// ... other properties and methods
}
Client-side validation requires including the necessary JavaScript libraries (e.g., jQuery Validation) and rendering validation tags in your Razor markup.
Dependency Injection
Razor Pages seamlessly integrates with ASP.NET Core's built-in Dependency Injection system. You can inject services into your Page Models to access them:
using Microsoft.AspNetCore.Mvc.RazorPages;
public class DataPageModel : PageModel
{
private readonly IMyDataService _dataService;
public DataPageModel(IMyDataService dataService)
{
_dataService = dataService;
}
public void OnGet()
{
var data = _dataService.GetData();
// ... use data
}
}
Advanced Topics
Explore further for: