ASP.Net MVC Razor Syntax

27 Dec 2019

ASP.NET MVC Razor Syntax which is rendered via the Razor View Engine has been around a while. Razor is the new defacto standard for server rendered ASP.NET web applications, having surpassed the ASP.NET Web Forms technology due to its ease and flexibility particularly due to its natural melding of C# and HTML syntax, design time error detection and template capabilities.

The Razor syntax is used in Razor Pages, MVC and Blazor web app technologies, although not all technologies implement the full syntax.

Source - Syntax Reference

The @ character transitions from HTML to Razor syntax

Enabling Razor Pages

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        // Enable the Razor View Engine
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            // Map the Razor pages to endpoints
            endpoints.MapRazorPages();
        });
    }
}

Control Structures

@if, else if and else statements

@if (value % 2 == 0)
{
    <p>The value was even.</p>
}
else if (value >= 1337)
{
    <p>The value is large.</p>
}
else
{
    <p>The value is odd and small.</p>
}

@switch case statement

@switch (value)
{
    case 1:
        <p>The value is 1!</p>
        break;
    case 1337:
        <p>Your number is 1337!</p>
        break;
    default:
        <p>Your number wasn't 1 or 1337.</p>
        break;
}

@for loop statement

@for (var i = 0; i < people.Length; i++)
{
    var person = people[i];
    <p>Name: @person.Name</p>
    <p>Age: @person.Age</p>
}

@foreach statement

@foreach (var person in people)
{
    <p>Name: @person.Name</p>
    <p>Age: @person.Age</p>
}

@while statement

@{ var i = 0; }
@while (i < people.Length)
{
    var person = people[i];
    <p>Name: @person.Name</p>
    <p>Age: @person.Age</p>

    i++;
}

@do while statement

@{ var i = 0; }
@do
{
    var person = people[i];
    <p>Name: @person.Name</p>
    <p>Age: @person.Age</p>

    i++;
} while (i < people.Length);

Compound @using statements

@using (Html.BeginForm())
{
    <div>
        Email: <input type="email" id="Email" value="">
        <button>Register</button>
    </div>
}

@try, catch, finally statement

@try
{
    throw new InvalidOperationException("You did something invalid.");
}
catch (Exception ex)
{
    <p>The exception message: @ex.Message</p>
}
finally
{
    <p>The finally statement.</p>
}

@lock statement

@lock (SomeLock)
{
    // Do critical section work
}

Comments

Comments inside razor syntax are not rendered, however comments inside HTML syntax are rendered
@{
    /* C# comment */
    // Another C# comment
}
<!-- HTML comment -->

Directives

@

@{
    var quote = "Getting old ain't for wimps! - Anonymous";
}

<div>Quote of the Day: @quote</div>

which generates csharp at runtime similar to the following

public class _Views_Something_cshtml : RazorPage<dynamic>
{
    public override async Task ExecuteAsync()
    {
        var output = "Getting old ain't for wimps! - Anonymous";

        WriteLiteral("/r/n<div>Quote of the Day: ");
        Write(output);
        WriteLiteral("</div>");
    }
}

@attribute

@attribute [Authorize]

@code

@code {
    // C# members (fields, properties, and methods)
}

@functions

@functions {
    public string GetHello()
    {
        return "Hello";
    }
}

<div>From method: @GetHello()</div>

Which generates the following HTML

<div>From method: Hello</div>

from the generated Razor C# class

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Razor;

public class _Views_Home_Test_cshtml : RazorPage<dynamic>
{
    // Functions placed between here
    public string GetHello()
    {
        return "Hello";
    }
    // And here.
#pragma warning disable 1998
    public override async Task ExecuteAsync()
    {
        WriteLiteral("\r\n<div>From method: ");
        Write(GetHello());
        WriteLiteral("</div>\r\n");
    }
#pragma warning restore 1998

Another useful example is the creation of template methods

@{
    RenderName("Mahatma Gandhi");
    RenderName("Martin Luther King, Jr.");
}

@functions {
    private void RenderName(string name)
    {
        <p>Name: <strong>@name</strong></p>
    }
}

@implements

@implements IDisposable

<h1>Example</h1>

@functions {
    private bool _isDisposed;

    ...

    public void Dispose() => _isDisposed = true;
}

@inherits

@inherits TypeNameOfClassToInheritFrom

An example of the generated C# class

using Microsoft.AspNetCore.Mvc.Razor;

public abstract class CustomRazorPage<TModel> : RazorPage<TModel>
{
    public string CustomText { get; } =
        "Gardyloo! - A Scottish warning yelled from a window before dumping" +
        "a slop bucket on the street below.";
}

The CustomText is displayed in a view:

@inherits CustomRazorPage<TModel>

<div>Custom text: @CustomText</div>

Which renders the following HTML

<div>
    Custom text: Gardyloo! - A Scottish warning yelled from a window before dumping
    a slop bucket on the street below.
</div>

@inherits and @model are supported in the same view

@inherits CustomRazorPage<TModel>

<div>The Login Email: @Model.Email</div>
<div>Custom text: @CustomText</div>

@inject

@model

@model LoginViewModel

Which generates the following C# class, which inherits from RazorPage<dynamic>

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel> {
    ...
}

@namespace

@namespace Your.Namespace.Here

@page

@section

<html>
    <head>
        ...
    </head>
    <body>
        ...
        @RenderSection("Scripts", required: false)
    </body>
</html>

Where the Scripts section is defined in a child view

@section Scripts {
     <script type="text/javascript" src="~/scripts/main.js"></script>
}

Which will render as follows

<html>
    <head>
        ...
    </head>
    <body>
        ...
        <script type="text/javascript" src="~/scripts/main.js"></script>
    </body>
</html>

@using

@using System.IO
@{
    var dir = Directory.GetCurrentDirectory();
}
<p>@dir</p>

Razor Components

Requires using the Blazor file syntax, using a .razor file extension

Simple Razor components extend the existing Razor syntax, allowing dynamically defined members to be late interpretted when rendering the page response.

<h1 style="font-style:@_headingFontStyle">@_headingText</h1>

@code {
    private string _headingFontStyle = "italic";
    private string _headingText = "Put on your new Blazor!";
}

Blazor

Blazor is a framework for building interactive client-side web UI with .NET:

Using .NET for client-side web development offers the following advantages:

Blazor - Further Reading