AspNetCore.Docs/aspnetcore/mvc/views/razor.md

599 lines
16 KiB
Markdown
Raw Normal View History

2016-10-29 01:35:15 +08:00
---
2016-11-17 08:24:57 +08:00
title: Razor Syntax Reference | Microsoft Docs
2016-10-29 01:35:15 +08:00
author: rick-anderson
2016-11-18 04:13:02 +08:00
description:
keywords: ASP.NET Core,
2016-10-29 01:35:15 +08:00
ms.author: riande
manager: wpickett
ms.date: 01/14/2017
2016-10-29 01:35:15 +08:00
ms.topic: article
ms.assetid: a89a8433-8b0e-4795-a73a-82114d27e233
2016-11-17 08:24:57 +08:00
ms.technology: aspnet
2016-10-29 01:35:15 +08:00
ms.prod: aspnet-core
uid: mvc/views/razor
---
# Razor syntax
2016-10-29 01:35:15 +08:00
2016-12-05 13:01:40 +08:00
By [Taylor Mullen](https://twitter.com/ntaylormullen) and [Rick Anderson](https://twitter.com/RickAndMSFT)
2016-10-29 01:35:15 +08:00
## What is Razor?
Razor is a markup syntax for embedding server based code into web pages. The Razor syntax consists of Razor markup, C# and HTML. Files containing Razor generally have a *.cshtml* file extension.
## Rendering HTML
The default Razor language is HTML. Rendering HTML from Razor is no different than in an HTML file. A Razor file with the following markup:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<p>Hello World</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Is rendered unchanged as `<p>Hello World</p>` by the server.
## 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. Razor can transition from HTML into C# or into Razor specific markup. When an `@` symbol is followed by a [Razor reserved keyword](#razor-reserved-keywords) it transitions into Razor specific markup, otherwise it transitions into plain C# .
2016-10-29 01:35:15 +08:00
<a name=escape-at-label></a>
HTML containing `@` symbols may need to be escaped with a second `@` symbol. For example:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<p>@@Username</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
would render the following HTML:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<p>@Username</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
<a name=razor-email-ref></a>
HTML attributes and content containing email addresses dont treat the `@` symbol as a transition character.
`<a href="mailto:Support@contoso.com">Support@contoso.com</a>`
## Implicit Razor expressions
Implicit Razor expressions start with `@` followed by C# code. For example:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<p>@DateTime.Now</p>
<p>@DateTime.IsLeapYear(2016)</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
With the exception of the C# `await` keyword implicit expressions must not contain spaces. For example, you can intermingle spaces as long as the C# statement has a clear ending:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<p>@await DoSomething("hello", "world")</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
<a name=explicit-razor-expressions></a>
## Explicit Razor expressions
Explicit Razor expressions consists of an @ symbol with balanced parenthesis. For example, to render last weeks time:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<p>Last week this time: @(DateTime.Now - TimeSpan.FromDays(7))</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Any content within the @() parenthesis is evaluated and rendered to the output.
Implicit expressions generally cannot contain spaces. For example, in the code below, one week is not subtracted from the current time:
[!code-html[Main](razor/sample/Views/Home/Contact.cshtml?range=20)]
Which renders the following HTML:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<p>Last week: 7/7/2016 4:39:52 PM - TimeSpan.FromDays(7)</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
You can use an explicit expression to concatenate text with an expression result:
<!-- literal_block {"ids": [], "linenos": false, "xml:space": "preserve", "language": "none", "highlight_args": {"hl_lines": [5]}} -->
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@{
var joe = new Person("Joe", 33);
}
<p>Age@(joe.Age)</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Without the explicit expression, `<p>Age@joe.Age</p>` would be treated as an email address and `<p>Age@joe.Age</p>` would be rendered. When written as an explicit expression, `<p>Age33</p>` is rendered.
<a name=expression-encoding-label></a>
## 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 are rendered. For example, the following Razor markup:
2016-10-29 01:35:15 +08:00
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
@("<span>Hello World</span>")
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Renders this HTML:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
&lt;span&gt;Hello World&lt;/span&gt;
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Which the browser renders as:
`<span>Hello World</span>`
`HtmlHelper` `Raw` output is not encoded but rendered as HTML markup.
2016-10-29 01:35:15 +08:00
>[!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` on user input.
The following Razor markup:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
@Html.Raw("<span>Hello World</span>")
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Renders this HTML:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<span>Hello World</span>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
<a name=razor-code-blocks-label></a>
## Razor code blocks
Razor code blocks start with `@` and are enclosed by `{}`. Unlike expressions, C# code inside code blocks is not rendered. Code blocks and expressions in a Razor page share the same scope and are defined in order (that is, declarations in a code block will be in scope for later code blocks and expressions).
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@{
var output = "Hello World";
}
<p>The rendered result: @output</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Would render:
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<p>The rendered result: Hello World</p>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
<a name=implicit-transitions-label></a>
### Implicit transitions
The default language in a code block is C#, but you can transition back to HTML. HTML within a code block will transition back into rendering HTML:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@{
var inCSharp = true;
<p>Now in HTML, was in C# @inCSharp</p>
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
<a name=explicit-delimited-transition-label></a>
### Explicit delimited transition
To define a sub-section of a code block that should render HTML, surround the characters to be rendered with the Razor `<text>` tag:
<!-- literal_block {"ids": [], "linenos": false, "xml:space": "preserve", "language": "none", "highlight_args": {"hl_lines": [4]}} -->
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
<text>Name: @person.Name</text>
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
You generally use this approach when you want to render HTML that is not surrounded by an HTML tag. Without an HTML or Razor tag, you get a Razor runtime error.
<a name=explicit-line-transition-with-label></a>
### Explicit Line Transition with `@:`
To render the rest of an entire line as HTML inside a code block, use the `@:` syntax:
<!-- literal_block {"ids": [], "linenos": false, "xml:space": "preserve", "language": "none", "highlight_args": {"hl_lines": [4]}} -->
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
@:Name: @person.Name
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Without the `@:` in the code above, you'd get a Razor run time error.
<a name=control-structures-razor-label></a>
## 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`
The `@if` family controls when code runs:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@if (value % 2 == 0)
{
<p>The value was even</p>
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
`else` and `else if` don't require the `@` symbol:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@if (value % 2 == 0)
{
<p>The value was even</p>
}
else if (value >= 1337)
{
<p>The value is large.</p>
}
else
{
<p>The value was not large and is odd.</p>
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
You can use a switch statement like this:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@switch (value)
{
case 1:
<p>The value is 1!</p>
break;
case 1337:
<p>Your number is 1337!</p>
break;
default:
<p>Your number was not 1 or 1337.</p>
break;
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
### Looping `@for`, `@foreach`, `@while`, and `@do while`
You can render templated HTML with looping control statements. For example, to render a list of people:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@{
var people = new Person[]
{
new Person("John", 33),
new Person("Doe", 41),
};
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
You can use any of the following looping statements:
`@for`
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@for (var i = 0; i < people.Length; i++)
{
var person = people[i];
<p>Name: @person.Name</p>
<p>Age: @person.Age</p>
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
`@foreach`
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@foreach (var person in people)
{
<p>Name: @person.Name</p>
<p>Age: @person.Age</p>
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
`@while`
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@{ var i = 0; }
@while (i < people.Length)
{
var person = people[i];
<p>Name: @person.Name</p>
<p>Age: @person.Age</p>
i++;
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
`@do while`
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@{ var i = 0; }
@do
{
var person = people[i];
<p>Name: @person.Name</p>
<p>Age: @person.Age</p>
i++;
} while (i < people.Length);
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
### Compound `@using`
In C# a using statement is used to ensure an object is disposed. In Razor this same mechanism can be used to create [HTML helpers](html-helpers.md) that contain additional content. For instance, we can utilize [🔧 HTML Helpers](html-helpers.md) to render a form tag with the `@using` statement:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@using (Html.BeginForm())
{
<div>
email:
<input type="email" id="Email" name="Email" value="" />
<button type="submit"> Register </button>
</div>
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
You can also perform scope level actions like the above with [Tag Helpers](tag-helpers/index.md).
### `@try`, `catch`, `finally`
Exception handling is similar to C#:
[!code-html[Main](razor/sample/Views/Home/Contact7.cshtml)]
### `@lock`
Razor has the capability to protect critical sections with lock statements:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@lock (SomeLock)
{
// Do critical section work
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
### Comments
Razor supports C# and HTML comments. The following markup:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@{
/* C# comment. */
// Another C# comment.
}
<!-- HTML comment -->
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Is rendered by the server as:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
<!-- HTML comment -->
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Razor comments are removed by the server before the page is rendered. Razor uses `@* *@` to delimit comments. The following code is commented out, so the server will not render any markup:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@*
@{
/* C# comment. */
// Another C# comment.
}
<!-- HTML comment -->
*@
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
<a name=razor-directives-label></a>
## Directives
Razor directives are represented by implicit expressions with reserved keywords following the `@` symbol. A directive will typically change the way a page is parsed or enable different functionality within your Razor page.
Understanding how Razor generates code for a view will make it easier to understand how directives work. A Razor page is used to generate a C# file. For example, this Razor page:
[!code-html[Main](razor/sample/Views/Home/Contact8.cshtml)]
Generates a class similar to the following:
2016-11-18 13:03:07 +08:00
```csharp
2016-10-29 01:35:15 +08:00
public class _Views_Something_cshtml : RazorPage<dynamic>
{
public override async Task ExecuteAsync()
{
var output = "Hello World";
WriteLiteral("/r/n<div>Output: ");
Write(output);
WriteLiteral("</div>");
}
}
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
[Viewing the Razor C# class generated for a view](#razor-customcompilationservice-label) explains how to view this generated class.
2016-10-29 01:35:15 +08:00
### `@using`
The `@using` directive will add the c# `using` directive to the generated razor page:
[!code-html[Main](razor/sample/Views/Home/Contact9.cshtml)]
### `@model`
The `@model` directive allows you to specify the type of the model passed to your Razor page. It uses the following syntax:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@model TypeNameOfModel
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
For example, if you create an ASP.NET Core MVC app with individual user accounts, the *Views/Account/Login.cshtml* Razor view contains the following model declaration:
2016-11-18 13:03:07 +08:00
```csharp
2016-10-29 01:35:15 +08:00
@model LoginViewModel
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
In the class example in , the class generated inherits from `RazorPage<dynamic>`. By adding an `@model` you control whats inherited. For example
2016-11-18 13:03:07 +08:00
```csharp
2016-10-29 01:35:15 +08:00
@model LoginViewModel
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Generates the following class
2016-11-18 13:03:07 +08:00
```csharp
2016-10-29 01:35:15 +08:00
public class _Views_Account_Login_cshtml : RazorPage<LoginViewModel>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
Razor pages expose a `Model` property for accessing the model passed to the page.
2016-11-18 13:03:07 +08:00
```html
2016-10-29 01:35:15 +08:00
<div>The Login Email: @Model.Email</div>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
The `@model` directive specified the type of this property (by specifying the `T` in `RazorPage<T>` that the generated class for your page derives from). If you don't specify the `@model` directive the `Model` property will be of type `dynamic`. The value of the model is passed from the controller to the view. See [Strongly typed models and the @model keyword](../../tutorials/first-mvc-app/adding-model.md#strongly-typed-models-keyword-label) for more information.
### `@inherits`
The `@inherits` directive gives you full control of the class your Razor page inherits:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@inherits TypeNameOfClassToInheritFrom
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
For instance, lets say we had the following custom Razor page type:
[!code-csharp[Main](razor/sample/Classes/CustomRazorPage.cs)]
The following Razor would generate `<div>Custom text: Hello World</div>`.
[!code-html[Main](razor/sample/Views/Home/Contact10.cshtml)]
You can't use `@model` and `@inherits` on the same page. You can have `@inherits` in a *_ViewImports.cshtml* file that the Razor page imports. For example, if your Razor view imported the following *_ViewImports.cshtml* file:
[!code-html[Main](razor/sample/Views/_ViewImportsModel.cshtml)]
The following strongly typed Razor page
[!code-html[Main](razor/sample/Views/Home/Login1.cshtml)]
Generates this HTML markup:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
<div>The Login Email: Rick@contoso.com</div>
<div>Custom text: Hello World</div>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
When passed "[Rick@contoso.com](mailto:Rick@contoso.com)" in the model:
See [Layout](layout.md) for more information.
### `@inject`
The `@inject` directive enables you to inject a service from your [service container](../../fundamentals/dependency-injection.md) into your Razor page for use. See [Dependency injection into views](dependency-injection.md).
### `@functions`
The `@functions` directive enables you to add function level content to your Razor page. The syntax is:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
@functions { // C# Code }
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
For example:
[!code-html[Main](razor/sample/Views/Home/Contact6.cshtml)]
Generates the following HTML markup:
2016-11-18 13:03:07 +08:00
```none
2016-10-29 01:35:15 +08:00
<div>From method: Hello</div>
2016-11-18 13:03:07 +08:00
```
2016-10-29 01:35:15 +08:00
The generated Razor C# looks like:
[!code-csharp[Main](razor/sample/Classes/Views_Home_Test_cshtml.cs?range=1-19)]
### `@section`
The `@section` directive is used in conjunction with the [layout page](layout.md) to enable views to render content in different parts of the rendered HTML page. See [Sections](layout.md#layout-sections-label) for more information.
## TagHelpers
The following [Tag Helpers](tag-helpers/index.md) directives are detailed in the links provided.
* [@addTagHelper](tag-helpers/intro.md#add-helper-label)
* [@removeTagHelper](tag-helpers/intro.md#remove-razor-directives-label)
* [@tagHelperPrefix](tag-helpers/intro.md#prefix-razor-directives-label)
<a name=razor-reserved-keywords-label></a>
## Razor reserved keywords
### Razor keywords
* functions
* inherits
* model
* section
* helper (Not supported by ASP.NET Core.)
Razor keywords can be escaped with `@(Razor Keyword)`, for example `@(functions)`. See the complete sample below.
### C# Razor keywords
* case
* do
* default
* for
* foreach
* if
* lock
* switch
* try
* using
* while
C# Razor keywords need to be double escaped with `@(@C# Razor Keyword)`, for example `@(@case)`. The first `@` escapes the Razor parser, the second `@` escapes the C# parser. See the complete sample below.
### Reserved keywords not used by Razor
* namespace
* class
## View compilation
Razor views are compiled at runtime when the view is invoked. If you prefer to compile your Razor views and deploy them with your app make these changes to *project.json*:
1. Add a reference to "Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Design" under the "dependencies" section.
2. Add a reference to "Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Tools" under the "tools" section.
3. Add a postpublish script to invoke the view compiler:
```
"scripts": {
"postpublish": [ "dotnet razor-precompile --configuration %publish:Configuration% --framework %publish:TargetFramework% --output-path %publish:OutputPath% %publish:ProjectPath%" ]
}
```
2016-10-29 01:35:15 +08:00
<a name=razor-customcompilationservice-label></a>
## Viewing the Razor C# class generated for a view
Add the following class to your ASP.NET Core MVC project:
[!code-csharp[Main](razor/sample/Services/CustomCompilationService.cs)]
Override the `ICompilationService` added by MVC with the above class;
2016-10-29 01:35:15 +08:00
[!code-csharp[Main](razor/sample/Startup.cs?highlight=4&range=29-33)]
Set a break point on the `Compile` method of `CustomCompilationService` and view `compilationContent`.
![Text Visualizer view of compilationContent](razor/_static/tvr.png)