Skip to main content This browser is no longer supported. Show
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support. Razor syntax reference for ASP.NET Core
In this articleBy Rick Anderson, Taylor Mullen, and Dan Vicarel Razor is a markup syntax for embedding .NET based code into webpages. The Razor syntax consists of Razor markup, C#, and HTML. Files containing Razor generally have a Introduction to ASP.NET Web Programming Using the Razor Syntax provides many samples of programming with Razor syntax. Although the topic was written for ASP.NET rather than ASP.NET Core, most of the samples apply to ASP.NET Core. Rendering HTMLThe default Razor language is HTML. Rendering HTML from Razor markup is no different than rendering HTML from an HTML file. HTML markup in Razor syntaxRazor supports C# and uses the When an To escape an
The code is rendered in HTML with a
single
HTML attributes and content containing email addresses don't treat the
Scalable Vector Graphics (SVG)SVG foreignObject elements are supported:
Implicit Razor expressionsImplicit Razor expressions start with
With the exception of the C#
Implicit expressions
cannot contain C# generics, as the characters inside the brackets (
The preceding code generates a compiler error similar to one of the following:
Generic method calls must be wrapped in an explicit Razor expression or a Razor code block. Explicit Razor expressionsExplicit Razor
expressions consist of an
Any content within the Implicit expressions, described in the previous section, generally can't contain spaces. In the following code, one week isn't subtracted from the current time:
The code renders the following HTML:
Explicit expressions can be used to concatenate text with an expression result:
Without the explicit expression, Explicit expressions can be used to render output from generic methods in
Expression encodingC# expressions that evaluate to a string are HTML encoded. C# expressions that evaluate to
The preceding code renders the following HTML:
The HTML is shown in the browser as plain text: <span>Hello World</span>
Warning Using
The code renders the following HTML:
Razor code blocksRazor code blocks start with
The code renders the following HTML:
In code blocks, declare local functions with markup to serve as templating methods:
The code renders the following HTML:
Implicit transitionsThe default language in a code block is C#, but the Razor Page can transition back to HTML:
Explicit delimited transitionTo define a subsection of a code block that should render HTML, surround the characters for rendering with the Razor
Use this approach to render HTML that isn't surrounded by an HTML tag. Without an HTML or Razor tag, a Razor runtime error occurs. The
Explicit line transitionTo render the rest of an entire line as HTML inside a code block, use
Without the Extra Control structuresControl structures are an extension of code blocks. All aspects of code blocks (transitioning to markup, inline C#) also apply to the following structures: Conditionals @if, else if, else, and @switch
The following markup shows how to use a switch statement:
Looping @for, @foreach, @while, and @do whileTemplated HTML can be rendered with looping control statements. To render a list of people:
The following looping statements are supported:
Compound @usingIn C#, a
@try, catch, finallyException handling is similar to C#:
|
Page | Namespace |
---|---|
Pages/Index.cshtml
| Hello.World
|
Pages/MorePages/Page.cshtml
| Hello.World.MorePages
|
Pages/MorePages/EvenMorePages/Page.cshtml
| Hello.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.
Page | Namespace |
---|---|
Pages/Index.cshtml
| Hello.World
|
Pages/MorePages/Page.cshtml
| Hello.World.MorePages
|
Pages/MorePages/EvenMorePages/Page.cshtml
| Another.Planet
|
@page
The @page
directive has different effects depending on the type of the file where it appears. The directive:
- In a
.cshtml
file indicates that the file is a Razor Page. For more information, see Custom routes and Introduction to Razor Pages in ASP.NET Core. - Specifies that a Razor component should handle requests directly. For more information, see ASP.NET Core Blazor routing and navigation.
@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:
- Leading or trailing within an element.
- Leading or trailing within a
RenderFragment
parameter. For example, child content passed to another component. - It precedes or follows
a C# code block, such as
@if
or@foreach
.
@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. For more
information, see Layout in ASP.NET Core.
@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. For
more information, see ASP.NET Core Razor components.
@bind
This scenario only applies to Razor components (.razor
).
Data binding in components is accomplished with the @bind
attribute. For more information, see
ASP.NET Core Blazor data binding.
@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. For more information, see ASP.NET Core Blazor globalization and localization.
@on{EVENT}
This
scenario only applies to Razor components (.razor
).
Razor provides event handling features for components. For more information, see ASP.NET Core Blazor event handling.
@on{EVENT}:preventDefault
This scenario only applies to Razor components (.razor
).
Prevents the default action for the event.
@on{EVENT}:stopPropagation
This scenario only applies to Razor components (.razor
).
Stops event propagation for the event.
@key
This scenario only applies to Razor components (.razor
).
The @key
directive attribute causes the components diffing algorithm to guarantee preservation of elements or components based on the key's value. For more information, see
ASP.NET Core Razor components.
@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. For more information, see
ASP.NET Core Razor components.
Templated Razor delegates
Razor templates allow you to define a UI snippet with the following format:
@<tag>...</tag>
The following example illustrates how to specify a templated Razor delegate as a
Func<T,TResult>. The dynamic type is specified for the parameter of the method that the delegate encapsulates. An object type is specified as the return value of the delegate. The template is used with a List<T> of Pet
that has a Name
property.
public class Pet
{
public string Name { get; set; }
}
@{
Func<dynamic, object> petTemplate = @<p>You have a pet named <strong>@item.Name</strong>.</p>;
var pets = new List<Pet>
{
new Pet { Name = "Rin Tin Tin" },
new Pet { Name = "Mr. Bigglesworth" },
new Pet { Name = "K-9" }
};
}
The template is rendered with pets
supplied by a foreach
statement:
@foreach (var pet in pets)
{
@petTemplate(pet)
}
Rendered output:
<p>You have a pet named <strong>Rin Tin Tin</strong>.</p>
<p>You have a pet named <strong>Mr. Bigglesworth</strong>.</p>
<p>You have a pet named <strong>K-9</strong>.</p>
You can also supply an inline Razor template
as an argument to a method. In the following example, the Repeat
method receives a Razor template. The method uses the template to produce HTML content with repeats of items supplied from a list:
@using Microsoft.AspNetCore.Html
@functions {
public static IHtmlContent Repeat(IEnumerable<dynamic> items, int times,
Func<dynamic, IHtmlContent> template)
{
var html = new HtmlContentBuilder();
foreach (var item in items)
{
for (var i = 0; i < times; i++)
{
html.AppendHtml(template(item));
}
}
return html;
}
}
Using the list of pets from the prior example, the Repeat
method is called with:
- List<T> of
Pet
. - Number of times to repeat each pet.
- Inline template to use for the list items of an unordered list.
<ul>
@Repeat(pets, 3, @<li>@item.Name</li>)
</ul>
Rendered output:
<ul>
<li>Rin Tin Tin</li>
<li>Rin Tin Tin</li>
<li>Rin Tin Tin</li>
<li>Mr. Bigglesworth</li>
<li>Mr. Bigglesworth</li>
<li>Mr. Bigglesworth</li>
<li>K-9</li>
<li>K-9</li>
<li>K-9</li>
</ul>
Tag Helpers
This scenario only applies to MVC views and Razor Pages (.cshtml
).
There are three directives that pertain to Tag Helpers.
Directive | Function |
---|---|
@addTagHelper
| Makes Tag Helpers available to a view. |
@removeTagHelper
| Removes Tag Helpers previously added from a view. |
@tagHelperPrefix
| Specifies a tag prefix to enable Tag Helper support and to make Tag Helper usage explicit. |
Razor reserved keywords
Razor keywords
page
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.
Reserved keywords not used by Razor
class
Inspect the Razor C# class generated for a view
The Razor SDK handles compilation of Razor files. By default, the generated code files aren't emitted. To enable emitting the code files, set the EmitCompilerGeneratedFiles
directive in the
project file (.csproj
) to true
:
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
When building a 6.0 project (net6.0
) in the Debug
build configuration, the Razor SDK generates an obj/Debug/net6.0/generated/
directory in the project root. Its subdirectory contains the emitted Razor page code files.
The
Razor SDK handles compilation of Razor files. When building a project, the Razor SDK generates an obj/{BUILD CONFIGURATION}/{TARGET FRAMEWORK MONIKER}/Razor
directory in the project root. The directory structure within the Razor
directory mirrors the project's directory structure.
Consider the following directory structure in an ASP.NET Core Razor Pages 2.1 project:
Areas/
Admin/
Pages/
Index.cshtml
Index.cshtml.cs
Pages/
Shared/
_Layout.cshtml
_ViewImports.cshtml
_ViewStart.cshtml
Index.cshtml
Index.cshtml.cs
Building the
project in Debug
configuration yields the following obj
directory:
obj/
Debug/
netcoreapp2.1/
Razor/
Areas/
Admin/
Pages/
Index.g.cshtml.cs
Pages/
Shared/
_Layout.g.cshtml.cs
_ViewImports.g.cshtml.cs
_ViewStart.g.cshtml.cs
Index.g.cshtml.cs
To view the generated class for Pages/Index.cshtml
, open obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs
.
View lookups and case sensitivity
The Razor view engine performs case-sensitive lookups for views. However, the actual lookup is determined by the underlying file system:
- File based source:
- On operating systems with case insensitive file systems (for example, Windows),
physical file provider lookups are case insensitive. For example,
return View("Test")
results in matches for/Views/Home/Test.cshtml
,/Views/home/test.cshtml
, and any other casing variant. - On case-sensitive file systems (for example, Linux, OSX, and with
EmbeddedFileProvider
), lookups are case-sensitive. For example,return View("Test")
specifically matches/Views/Home/Test.cshtml
.
- On operating systems with case insensitive file systems (for example, Windows),
physical file provider lookups are case insensitive. For example,
- Precompiled views: With ASP.NET Core 2.0 and later, looking up precompiled views is case insensitive on all operating systems. The behavior is identical to physical file provider's behavior on Windows. If two precompiled views differ only in case, the result of lookup is non-deterministic.
Developers are encouraged to match the casing of file and directory names to the casing of:
- Area, controller, and action names.
- Razor Pages.
Matching case ensures the deployments find their views regardless of the underlying file system.
Imports used by Razor
The following imports are generated by the ASP.NET Core web templates to support Razor Files:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
Additional resources
Introduction to ASP.NET Web Programming Using the Razor Syntax provides many samples of programming with Razor syntax.
Feedback
Submit and view feedback for