(C# ASP.NET Core) Beginner's Introduction to Razor Pages

This is the simplest introduction to Razor Pages - why you need them, what they are, and how page events and data could be handled with them. See the linked video for a primer information.
(Rev. 18-Jun-2024)

Categories | About |     |  


Why do you need a Razor Page?

We already know that a web server serves an html markup to your browser. The browser interprets various tags and generates the display of a web page.

In most cases, the server can send that markup by reading a static html page and streaming the bytes to the browser. For example, an html document on some historical event can be immediately read and sent as-is to the requesting client.

But consider a web page which has 99% content as static, but it shows the current server time in one of the tags, say, <h1>01:20:21 AM</h1>? Such a page cannot be served merely by reading it - the current time must, first, be programmatically determined - and then substituted in the h1 tag. Pages of this kind are called dynamic pages.

But how does a server know which page is dynamic? and which static? The convention is that pages of certain extensions like html, htm are considered static, whereas a particular server side framework can declare certain extensions to be of dynamic type. For example, a PHP server uses .php extension for dynamic pages.

Now coming to ASP.NET Core - here dynamic pages are called Razor Pages and they have an extension .cshtml.

A server passes a razor page through a processing pipeline before serving it, even if it contains 100% static content. The processing function "looks for" the portions that need substitutions.

Video Explanation

Please watch the following youtube video:

What exactly is a Razor Page?
(also see the linked video)

A razor page contains static parts of pure html tags interspersed with a syntax called razor markup. The razor markup is processed through a C# code to make the substitutions.

Consider a razor page below. It starts with an @page directive, and the remaining part looks like an html markup, except for the razor syntax @DateTime.Now.

Razor syntax starts with an @ character - which is followed by a C# code. This code executes and the result is directly substituted at that place.

// .cshtml razor file 

// this directive tells ASP.NET Core 
// that this is a razor page that must  
// be processed before serving 

<h1>Hello ASP.NET Core</h1>

<span>Current time is @DateTime.Now</span>

Backing class of a Razor Page
(also see the linked video)

If the code to be executed is too complex, then it is not practically possible to stuff the entire code into a single cshtml file.

A backing class is often attached to a razor page - the properties of that class are directly accessible from the razor page, and its methods/functions can be used to handle events such as of FORM posts, or of file uploads, or of other GET requests, etc.,

Hence, a razor page called Index, could actually be a pair of files - one called Index.cshtml and the other Index.cshtml.cs. The backing class must inherit from a class called PageModel like shown next.

// Index.cshtml.cs backing class 

// namespace directives 
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace MyRazorApp.Pages

  public class IndexModel : PageModel

    public void OnGet()




The Index.cshtml razor page is connected to this class through a directive called @model


// fully qualified path to the backing class 
@model MyRazorApp.Pages.IndexModel

// ***** remaining page follows ***** // 

We shall now proceed with details in the subsequent tutorials.

Middleware and Configuration
(also see the linked video)

Razor pages are not enable by default. You will need to (1) enable the services for razor pages, (2) enable the routing middleware and (3) add razor pages as the end-points for handling the HTTP requests.

Don't worry at this stage about terms like "middleware", etc., Just configure as suggested. These topics should and can be understood later only.

Following is the completed Startup class that shows the bare minimal configuration for razor pages to be functional. See the linked video for my comments.

// NOTE: some versions of ASP.NET core do 
// it differently, but idea is the same 
public class Startup

  public void ConfigureServices(IServiceCollection services)

    // First thing - enable the service for 
    // razor pages 


  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    if (env.IsDevelopment())



    // Secondly, enable the routing middleware 

    // thirdly, set razor pages as the 
    // end-points for handling the 
    // HTTP requests 
    app.UseEndpoints(endpoints =>





Exercises on Razor Pages

for solutions please join our Course on ASP.NET Core with Project ("Find a Doctor")
  1. Create an application consisting of a razor page called Index - but without its backing csharp file. The razor page should print your name.
  2. Display your name thus: Add a string variable called strName to the above page. Set the variable to your name. Then display the variable strName.
  3. Create an application consisting of a razor page called Index - but without its backing csharp file. Create two int variables i and j. Set i to 7 and j to 2. Display their sum using razor syntax.
  4. Create an application consisting of a razor page called Index and its backing csharp file. Create two int properties i and j in the backing class. Set i to 7 and j to 2. Display their sum using razor syntax.
  5. Add a function called, say, GetName to the razor page in the first exercise. The function has a return type of String and returns your name. Now display your name by calling the above function.

This Blog Post/Article "(C# ASP.NET Core) Beginner's Introduction to Razor Pages" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.