Razor supports both C# (C sharp) and VB (Visual Basic).
Main Razor Syntax Rules for C#
This article covers all of the basics needed to use Razor within ASP.NET Web Pages, and should provide a ready reference for those using the Razor View Engine within ASP.NET MVC 3 onwards. If you would like to know more about how the Razor parser actually works, and track its evolution, you should visit the blog of Dr Razor - Andrew Nurse. ASP.NET Razor Syntax Reference. GitHub Gist: instantly share code, notes, and snippets. Razor is a markup syntax for embedding server-based code into webpages. The Razor syntax consists of Razor markup, C#, and HTML. Files containing Razor generally have a.cshtml file extension. Razor is also found in Razor components files (.razor). The default Razor language is HTML.
- Razor code blocks are enclosed in @{ ... }
- Inline expressions (variables and functions) start with @
- Code statements end with semicolon
- Variables are declared with the var keyword
- Strings are enclosed with quotation marks
- C# code is case sensitive
- C# files have the extension .cshtml
C# Example
@{ var myMessage = 'Hello World'; }
<!-- Inline expression or variable -->
<p>The value of myMessage is: @myMessage</p>
<!-- Multi-statement block -->
@{
var greeting = 'Welcome to our site!';
var weekDay = DateTime.Now.DayOfWeek;
var greetingMessage = greeting + ' Here in Huston it is: ' + weekDay;
}
<p>The greeting is: @greetingMessage</p>
Main Razor Syntax Rules for VB
- Razor code blocks are enclosed in @Code ... End Code
- Inline expressions (variables and functions) start with @
- Variables are declared with the Dim keyword
- Strings are enclosed with quotation marks
- VB code is not case sensitive
- VB files have the extension .vbhtml
Example
@Code dim myMessage = 'Hello World' End Code
<!-- Inline expression or variable -->
<p>The value of myMessage is: @myMessage</p>
<!-- Multi-statement block -->
@Code
dim greeting = 'Welcome to our site!'
dim weekDay = DateTime.Now.DayOfWeek
dim greetingMessage = greeting & ' Here in Huston it is: ' & weekDay
End Code
<p>The greeting is: @greetingMessage</p>
How Does it Work?
Razor is a simple programming syntax for embedding server code in web pages.
Razor syntax is based on the ASP.NET framework, the part of the Microsoft.NET Framework that's specifically designed for creating web applications.
The Razor syntax gives you all the power of ASP.NET, but is using a simplified syntax that's easier to learn if you're a beginner, and makes you more productive if you're an expert.
Razor web pages can be described as HTML pages with two kinds of content: HTML content and Razor code.
When the server reads the page, it runs the Razor code first, before it sends the HTML page to the browser. The code that is executed on the server can perform tasks that cannot be done in the browser, for example accessing a server database. Server code can create dynamic HTML content on the fly, before it is sent to the browser. Seen from the browser, the HTML generated by server code is no different than static HTML content.
ASP.NET web pages with Razor syntax have the special file extension cshtml (Razor using C#) or vbhtml (Razor using VB).
Working With Objects
Server coding often involves objects.
The 'DateTime' object is a typical built-in ASP.NET object, but objects can also be self-defined, a web page, a text box, a file, a database record, etc.
Objects may have methods they can perform. A database record might have a 'Save' method, an image object might have a 'Rotate' method, an email object might have a 'Send' method, and so on.
Objects also have properties that describe their characteristics. A database record might have a FirstName and a LastName property (among others).
The ASP.NET DateTime object has a Now property (written as DateTime.Now), and the Now property has a Day property (written as DateTime.Now.Day). The example below shows how to access some properties of the DateTime object:
Example
<tr>
<th width='100px'>Name</th>
<td width='100px'>Value</td>
</tr>
<tr>
<td>Day</td><td>@DateTime.Now.Day</td>
</tr>
<tr>
<td>Hour</td><td>@DateTime.Now.Hour</td>
</tr>
<tr>
<td>Minute</td><td>@DateTime.Now.Minute</td>
</tr>
<tr>
<td>Second</td><td>@DateTime.Now.Second</td>
</tr>
</td>
</table>
If and Else Conditions
An important feature of dynamic web pages is that you can determine what to do based on conditions.
The common way to do this is with the if ... else statements:
Example
var txt = ';
if(DateTime.Now.Hour > 12)
{txt = 'Good Evening';}
else
{txt = 'Good Morning';}
}
<html>
<body>
<p>The message is @txt</p>
</body>
</html>
Reading User Input
Another important feature of dynamic web pages is that you can read user input.
Input is read by the Request[] function, and posting (input) is tested by the IsPost condition:
Example
var totalMessage = ';
if(IsPost)
{
var num1 = Request['text1'];
var num2 = Request['text2'];
var total = num1.AsInt() + num2.AsInt();
totalMessage = 'Total = ' + total;
}
}
<html>
<body>
<form action=' method='post'>
<p><label for='text1'>First Number:</label><br>
<input type='text' name='text1' /></p>
<p><label for='text2'>Second Number:</label><br>
<input type='text' name='text2' /></p>
<p><input type='submit' value=' Add ' /></p>
</form>
<p>@totalMessage</p>
</body>
</html>
-->
By Rick Anderson, Taylor Mullen, and Dan Vicarel
Razor is a markup syntax for embedding server-based code into webpages. The Razor syntax consists of Razor markup, C#, and HTML. Files containing Razor generally have a .cshtml file extension. Razor is also found in Razor components files (.razor).
Rendering HTML
The default Razor language is HTML. Rendering HTML from Razor markup is no different than rendering HTML from an HTML file. HTML markup in .cshtml Razor files is rendered by the server unchanged.
Razor syntax
Razor supports C# and uses the @
symbol to transition from HTML to C#. Razor evaluates C# expressions and renders them in the HTML output.
When an @
symbol is followed by a Razor reserved keyword, it transitions into Razor-specific markup. Otherwise, it transitions into plain C#.
To escape an @
symbol in Razor markup, use a second @
symbol:
The code is rendered in HTML with a single @
symbol:
HTML attributes and content containing email addresses don't treat the @
symbol as a transition character. The email addresses in the following example are untouched by Razor parsing:
Implicit Razor expressions
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:
Implicit expressions cannot contain C# generics, as the characters inside the brackets (<>
) are interpreted as an HTML tag. The following code is not valid:
The preceding code generates a compiler error similar to one of the following:
- The 'int' element wasn't closed. All elements must be either self-closing or have a matching end tag.
- Cannot convert method group 'GenericMethod' to non-delegate type 'object'. Did you intend to invoke the method?`
Generic method calls must be wrapped in an explicit Razor expression or a Razor code block.
Explicit Razor expressions
Explicit Razor expressions consist of an @
symbol with balanced parenthesis. To render last week's time, the following Razor markup is used:
Any content within the @()
parenthesis is evaluated and rendered to the output.
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, <p>Age@joe.Age</p>
is treated as an email address, and <p>Age@joe.Age</p>
is rendered. When written as an explicit expression, <p>Age33</p>
is rendered.
Explicit expressions can be used to render output from generic methods in .cshtml files. The following markup shows how to correct the error shown earlier caused by the brackets of a C# generic. The code is written as an explicit expression:
Expression encoding
C# expressions that evaluate to a string are HTML encoded. C# expressions that evaluate to IHtmlContent
are rendered directly through IHtmlContent.WriteTo
. C# expressions that don't evaluate to IHtmlContent
are converted to a string by ToString
and encoded before they're rendered.
The preceding code renders the following HTML:
The HTML is shown in the browser as plain text:
<span>Hello World</span>
HtmlHelper.Raw
output isn't encoded but rendered as HTML markup.
Warning
Using HtmlHelper.Raw
on unsanitized user input is a security risk. User input might contain malicious JavaScript or other exploits. Sanitizing user input is difficult. Avoid using HtmlHelper.Raw
with user input.
The code renders the following HTML:
Razor code blocks
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:
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 transitions
The default language in a code block is C#, but the Razor Page can transition back to HTML:
Explicit delimited transition
To define a subsection of a code block that should render HTML, surround the characters for rendering with the Razor <text>
tag:
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 <text>
tag is useful to control whitespace when rendering content:
- Only the content between the
<text>
tag is rendered. - No whitespace before or after the
<text>
tag appears in the HTML output.
Explicit line transition
To render the rest of an entire line as HTML inside a code block, use @:
syntax:
Without the @:
in the code, a Razor runtime error is generated.
Extra @
characters in a Razor file can cause compiler errors at statements later in the block. These compiler errors can be difficult to understand because the actual error occurs before the reported error. This error is common after combining multiple implicit/explicit expressions into a single code block.
Control structures
Control 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
@if
controls when code runs:
else
and else if
don't require the @
symbol:
The following markup shows how to use a switch statement:
Looping @for, @foreach, @while, and @do while
Templated HTML can be rendered with looping control statements. To render a list of people:
The following looping statements are supported:
@for
@foreach
@while
@do while
Compound @using
In C#, a using
statement is used to ensure an object is disposed. In Razor, the same mechanism is used to create HTML Helpers that contain additional content. In the following code, HTML Helpers render a <form>
tag with the @using
statement:
@try, catch, finally
Exception handling is similar to C#:
@lock
Razor has the capability to protect critical sections with lock statements:
Razor supports C# and HTML comments:
The code renders the following HTML:
Razor comments are removed by the server before the webpage is rendered. Razor uses @* *@
to delimit comments. The following code is commented out, so the server doesn't render any markup:
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.
The code generates a class similar to the following:
Later in this article, the section Inspect the Razor C# class generated for a view explains how to view this generated class.
@attribute
The @attribute
directive adds the given attribute to the class of the generated page or view. The following example adds the [Authorize]
attribute:
@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:
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:
In Razor components, use @code
over @functions
to add C# members.
For example:
The code generates the following HTML markup:
The following code is the generated Razor C# class:
@functions
methods serve as templating methods when they have markup:
The code renders the following HTML:
@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:
@inherits
The @inherits
directive provides full control of the class the view inherits:
The following code is a custom Razor page type:
The CustomText
is displayed in a view:
The code renders the following HTML:
@model
and @inherits
can be used in the same view. @inherits
can be in a _ViewImports.cshtml file that the view imports:
The following code is an example of a strongly-typed view:
If 'rick@contoso.com' is passed in the model, the view generates the following HTML markup:
@inject
The @inject
directive enables the Razor Page to inject a service from the service container into a view. For more information, see Dependency injection into views.
@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. For more information, see ASP.NET Core Blazor layouts.
@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:
In an ASP.NET Core MVC or Razor Pages app created with individual user accounts, Views/Account/Login.cshtml contains the following model declaration:
The class generated inherits from RazorPage<dynamic>
:
Razor exposes a Model
property for accessing the model passed to the view:
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:
- Sets the namespace of the class of the generated Razor page, MVC view, or Razor component.
- Sets the root derived namespaces of a pages, views, or components classes from the closest imports file in the directory tree, _ViewImports.cshtml (views or pages) or _Imports.razor (Razor components).
For the Razor Pages example shown in the following table:
- Each page imports Pages/_ViewImports.cshtml.
- Pages/_ViewImports.cshtml contains
@namespace Hello.World
. - Each page has
Hello.World
as the root of it's namespace.
Razor Syntax Download
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.
The @page
directive on the first line of a .cshtml file indicates that the file is a Razor Page. For more information, see Introduction to Razor Pages in ASP.NET Core.
@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:
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.
@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
Razor Syntax Cheat Sheet
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.
@typeparam
This scenario only applies to Razor components (.razor).
The @typeparam
directive declares a generic type parameter for the generated component class. For more information, see ASP.NET Core Blazor templated components.
Templated Razor delegates
Razor templates allow you to define a UI snippet with the following format:
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.
The template is rendered with pets
supplied by a foreach
statement:
Rendered output:
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 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.
Rendered output:
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
Razor Syntax Cheat Sheet
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.
Reserved keywords not used by Razor
class
Inspect the Razor C# class generated for a view
With .NET Core SDK 2.1 or later, 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 2.1 Razor Pages project targeting .NET Core 2.1:
Building the project in Debug configuration yields the following obj directory:
To view the generated class for Pages/Index.cshtml, open obj/Debug/netcoreapp2.1/Razor/Pages/Index.g.cshtml.cs.
Add the following class to the ASP.NET Core MVC project:
In Startup.ConfigureServices
, override the RazorTemplateEngine
added by MVC with the CustomTemplateEngine
class:
Set a breakpoint on the return csharpDocument;
statement of CustomTemplateEngine
. When program execution stops at the breakpoint, view the value of generatedCode
.
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.
Additional resources
Introduction to ASP.NET Web Programming Using the Razor Syntax provides many samples of programming with Razor syntax.