DEV Community


Learning Notes of Razor Page

Steve Mak
System Analyst & Technical Writer
・3 min read


Razor reserved keywords

Razor keywords

  • page (Requires ASP.NET Core 2.1 or later)
  • namespace
  • functions
  • inherits
  • model
  • section
  • helper (Not currently supported by ASP.NET Core)

Razor keywords are escaped with @(Razor Keyword) (for example, @(functions)).

C# Razor keywords

  • case
  • do
  • default
  • for
  • foreach
  • if
  • else
  • lock
  • switch
  • try
  • catch
  • finally
  • using
  • while

C# Razor keywords must be double-escaped with @(@C# Razor Keyword) (for example, @(@case)). The first @ escapes the Razor parser. The second @ escapes the C# parser.


To escape an @ symbol in Razor markup, use a second @ symbol (The code is rendered in HTML with a single @ symbol).


Implicit Razor expressions start with @ followed by C# code.


With the exception of the C# await keyword, implicit expressions must not contain spaces. If the C# statement has a clear ending, spaces can be intermingled.

<p>@await DoSomething("hello", "world")</p>

Explicit Razor expressions consist of an @ symbol with balanced parenthesis. To render last week's time, the following Razor markup is used.

<p>Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))</p>

Explicit expressions can be used to concatenate text with an expression result.

    var joe = new Person("Joe", 33);


Explicit expressions can be used to render output from generic methods in .cshtml files.


Razor code blocks start with @ and are enclosed by {}. Unlike expressions, C# code inside code blocks isn't rendered. Code blocks and expressions in a view share the same scope and are defined in order.

    var quote = "The future depends on what you do today. - Mahatma Gandhi";


    quote = "Hate cannot drive out hate, only love can do that. - Martin Luther King, Jr.";


The default language in a code block is C#, but the Razor Page can transition back to HTML.

    var inCSharp = true;
    <p>Now in HTML, was in C# @inCSharp</p>

To render the rest of an entire line as HTML inside a code block, use @: syntax.

@for (var i = 0; i < people.Length; i++)
    var person = people[i];
    @:Name: @person.Name

Handler Methods

The default convention works by matching the HTTP verb used for the request to the name of the method, which is prefixed with "On": OnGet(), OnPost(), OnPut() etc.

public void OnGet()
public void OnPost()
public void OnPut()
public Task OnPostAsync()
public Task OnGetAsync()

// Named Handler Methods
public void OnPostDelete()
public void OnPostEdit(int id)
public void OnPostView(int id)

// Sample form
<div class="row">
    <div class="col-lg-1">
        <form asp-page-handler="edit" asp-route-id="10" method="get">
            <button class="btn btn-default">Edit</button>
    <div class="col-lg-1">
        <form asp-page-handler="delete" asp-route-id="10" method="get">
            <button class="btn btn-default">Delete</button>
    <div class="col-lg-1">
        <form asp-page-handler="view" asp-route-id="10"  method="get">
            <button class="btn btn-default">View</button>

// If you prefer not to have query string values representing the handler's name in the URL, you can use routing to add an optional route value for "handler" as part of the route template in the @page directive:
@page "{handler?}/{id?}"

As far as the Razor Pages framework is concerned, OnGet and OnGetAsync are the same handler. You cannot have both in the same page. If you do, the framework will raise an exception.

Discussion (0)