Razor Pages is a page-based programming model introduced in ASP.NET Core 2.0 to simplify the process of building dynamic, server-side web applications. It’s built on top of the MVC (Model-View-Controller) pattern but provides a more streamlined, page-centric approach—ideal for developers who prefer working with page-focused architectures rather than the traditional controller-action structure.
With Razor Pages, each web page is self-contained, consisting of both the HTML markup and the logic required to handle user input and data. This design makes it easier to build, test, and maintain modern web applications in ASP.NET Core.
What is Razor Pages?
Razor Pages uses the Razor syntax, a lightweight templating engine that combines C# and HTML. Each Razor Page typically has two files:
A .cshtml file — contains HTML markup and Razor syntax.
A .cshtml.cs file — known as the PageModel, containing the C# backend logic for handling page events.
This structure allows developers to keep UI and logic separate but closely related, improving organization and readability.
Example. HelloWorld Razor Page
Index.cshtml
@page
@model RazorPagesDemo.Pages.IndexModel
@{
ViewData["Title"] = "Home Page";
}
<h1>Hello, @Model.Message!</h1>
Index.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPagesDemo.Pages
{
public class IndexModel : PageModel
{
public string Message { get; private set; } = "Welcome to Razor Pages!";
public void OnGet()
{
// Initialization logic here
}
}
}
Here:
The
@pagedirective makes the.cshtmlfile a Razor Page.The
IndexModelclass acts as the code-behind, handling page events.The
OnGet()method executes when the page is accessed via an HTTP GET request.
Project Setup for Razor Pages
Creating a Razor Pages project in Visual Studio or via CLI is simple.
Using .NET CLI
dotnet new webapp -n RazorPagesDemo
cd RazorPagesDemo
dotnet run
This command scaffolds a Razor Pages web application with the required folder structure.
Folder Structure
RazorPagesDemo/
│
├── Pages/
│ ├── Index.cshtml
│ ├── Index.cshtml.cs
│ └── Shared/
│ └── _Layout.cshtml
│
├── wwwroot/
├── Program.cs
└── appsettings.json
All Razor Pages reside inside the Pages folder by default, but you can organize them into subfolders for modularity.
How Razor Pages Works
When an HTTP request is made:
The ASP.NET Core Routing middleware maps the URL to a Razor Page.
The page’s PageModel executes the appropriate handler method (
OnGet,OnPost, etc.).The .cshtml view is rendered with the model’s data.
The final HTML response is sent to the browser.
Unlike MVC, there’s no need to define separate controllers or route configurations—the framework handles it automatically.
Handler Methods in Razor Pages
Each Razor Page can respond to different HTTP verbs using page handler methods:
OnGet()→ Handles HTTP GET requestsOnPost()→ Handles HTTP POST requestsOnPut()→ Handles HTTP PUT requestsOnDelete()→ Handles HTTP DELETE requests
Example. Handling Form Submissions
Contact.cshtml
@page
@model RazorPagesDemo.Pages.ContactModel
<h2>Contact Us</h2>
<form method="post">
<label>Name:</label>
<input type="text" asp-for="Name" />
<br/>
<label>Message:</label>
<textarea asp-for="Message"></textarea>
<br/>
<button type="submit">Submit</button>
</form>
@if (Model.IsSubmitted)
{
<p>Thanks, @Model.Name! Your message was received.</p>
}
Contact.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPagesDemo.Pages
{
public class ContactModel : PageModel
{
[BindProperty]
public string Name { get; set; }
[BindProperty]
public string Message { get; set; }
public bool IsSubmitted { get; set; } = false;
public void OnGet() { }
public void OnPost()
{
IsSubmitted = true;
}
}
}
The
[BindProperty]attribute binds form inputs directly to C# properties.OnPost()executes when the form is submitted.The view updates dynamically after submission.
Routing in Razor Pages
Routing is automatic in Razor Pages. The path to the .cshtml file defines the URL route.

Join the conversation! Your thoughts help the community grow.