Razor Directives

Directives

Razor directives are represented by implicit expressions with reserved keywords following the @ symbol. A directive typically changes the way a view is parsed or enables different functionality.

Understanding how Razor generates code for a view makes it easier to understand how directives work.

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

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

The code generates a class similar to the following:

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

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

@attribute

The @attribute directive adds the given attribute to the class of the generated page or view. The following example adds the [Authorize] attribute:

@attribute [Authorize]

The @attribute directive can also be used to supply a constant-based route template in a Razor component. In the following example, the @page directive in a component is replaced with the @attribute directive and the constant-based route template in Constants.CounterRoute, which is set elsewhere in the app to “/counter”:

@page "/counter"
@attribute [Route(Constants.CounterRoute)]

@code

This scenario only applies to Razor components (.razor).

The @code block enables a Razor component to add C# members (fields, properties, and methods) to a component:

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

For Razor components, @code is an alias of @functions and recommended over @functions. More than one @code block is permissible.

@functions

The @functions directive enables adding C# members (fields, properties, and methods) to the generated class:

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

In Razor components, use @code over @functions to add C# members.

For example:

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

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

The code generates the following HTML markup:

<div>From method: Hello</div>

The following code is 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

@functions methods serve as templating methods when they have markup:

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

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

The code renders the following HTML:

<p>Name: <strong>Mahatma Gandhi</strong></p>
<p>Name: <strong>Martin Luther King, Jr.</strong></p>

@implements

The @implements directive implements an interface for the generated class.

The following example implements System.IDisposable so that the Dispose method can be called:

@implements IDisposable

<h1>Example</h1>

@functions {
    private bool _isDisposed;

    ...

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

@inherits

The @inherits directive provides full control of the class the view inherits:

@inherits TypeNameOfClassToInheritFrom

The following code is a custom Razor page type:

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>

The code renders the following HTML:

<div>
    Custom text: Bumbershoot - Another word for an umbrella.
</div>

@model and @inherits can be used in the same view. @inherits can be in a _ViewImports.cshtml file that the view imports:

@inherits CustomRazorPage<TModel>

The following code is an example of a strongly-typed view:

@inherits CustomRazorPage<TModel>

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

If “jade@nuevofoundation.org ” is passed in the model, the view generates the following HTML markup:

<div>The Login Email: jade@nuevofoundation.org</div>
<div>
    Custom text: Bumbershoot - Another word for an umbrella.
</div>

@inject

The @inject directive enables the Razor Page to inject a service from the service container into a view.

@layout

This scenario only applies to Razor components (.razor).

The @layout directive specifies a layout for routable Razor components that have an @page directive. Layout components are used to avoid code duplication and inconsistency.

@model

This scenario only applies to MVC views and Razor Pages (.cshtml).

The @model directive specifies the type of the model passed to a view or page:

@model TypeNameOfModel

In an ASP.NET Core MVC or Razor Pages app created with individual user accounts, Views/Account/Login.cshtml contains the following model declaration:

@model LoginViewModel

The class generated inherits from RazorPage:

public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>

Razor exposes a Model property for accessing the model passed to the view:

<div>The Login Email: @Model.Email</div>

The @model directive specifies the type of the Model property. The directive specifies the T in RazorPage<T> that the generated class that the view derives from. If the @model directive isn’t specified, the Model property is of type dynamic. For more information, see Strongly typed models and the @model keyword.

@namespace

The @namespace directive:

@namespace Your.Namespace.Here

For the Razor Pages example shown in the following table:

PageNamespace
Pages/Index.cshtmlHello.World
Pages/MorePages/Page.cshtmlHello.World.MorePages
Pages/MorePages/EvenMorePages/Page.cshtmlHello.World.MorePages.EvenMorePages

The preceding relationships apply to import files used with MVC views and Razor components.

When multiple import files have a @namespace directive, the file closest to the page, view, or component in the directory tree is used to set the root namespace.

If the EvenMorePages folder in the preceding example has an imports file with @namespace Another.Planet (or the Pages/MorePages/EvenMorePages/Page.cshtml file contains @namespace Another.Planet), the result is shown in the following table.

PageNamespace
Pages/Index.cshtmlHello.World
Pages/MorePages/Page.cshtmlHello.World.MorePage
Pages/MorePages/EvenMorePages/Page.cshtmlAnother.Planet

@page

The @page directive has different effects depending on the type of the file where it appears. The directive:

@preservewhitespace

This scenario only applies to Razor components (.razor).

When set to false (default), whitespace in the rendered markup from Razor components (.razor) is removed if:

@section

This scenario only applies to MVC views and Razor Pages (.cshtml).

The @section directive is used in conjunction with MVC and Razor Pages layouts to enable views or pages to render content in different parts of the HTML page.

@typeparam

This scenario only applies to Razor components (.razor).

The @typeparam directive declares a generic type parameter for the generated component class:

@typeparam TEntity

Generic types with where type constraints are supported:

@typeparam TEntity where TEntity : IEntity

@using

The @using directive adds the C# using directive to the generated view:

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

In Razor components, @using also controls which components are in scope.

Directive attributes

Razor directive attributes are represented by implicit expressions with reserved keywords following the @ symbol. A directive attribute typically changes the way an element is parsed or enables different functionality.

@attributes

This scenario only applies to Razor components (.razor).

@attributes allows a component to render non-declared attributes.

@bind

This scenario only applies to Razor components (.razor).

Data binding in components is accomplished with the @bind attribute.

<input type="checkbox" @bind="todo.IsDone" />

This example binds the todo Object’s IsDone property to the checkbox.

@bind:culture

This scenario only applies to Razor components (.razor).

Use the @bind:culture attribute with the @bind attribute to provide a System.Globalization.CultureInfo for parsing and formatting a value.

@on{EVENT}

This scenario only applies to Razor components (.razor).

Razor provides event handling features for components.

<button @onclick="AddTodo">Add todo</button>

With this code, when someone clicks the button, it calls the AddToDo method.

@ref

This scenario only applies to Razor components (.razor).

Component references (@ref) provide a way to reference a component instance so that you can issue commands to that instance.

Razor reserved keywords

Razor keywords

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

C# Razor keywords

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.

Reserved keywords not used by Razor