Razor is a syntax that is used for creating templates, primarily in web applications and specifically in Blazor. Templates feature a mixture of HMTL and C# code. C# is separated from HTML in Razor primarily by the use of the @
character.
Basics
Values and the result of expressions can be rendered inline by prefixing them with the @
symbol:
<p>The time is @DateTime.Now</p>
<p>The discount is @(grossPrice * .1)</p>
Statements can be placed in code blocks which start with @{
and end with }
:
@{
var myInt = 1;
var myString = "Hello world!";
}
Control of flow statements can be embedded within HTML by prefixing the C# keyword with the @
token:
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
HTML tags must be matched inside and outside of the control of flow statements. If you want to render content that doesn't include any HTML, you have a couple of options. The first is to enclose the content in <text>
tags:
@if (forecasts == null)
{
<text>Loading...</text>
}
Alternatively, you can prefix each line of content with @:
@if (forecasts == null)
{
@:Loading...
}
The <text>
tags are preferred for multi-line content, or where it is necessary to work with unmatched HTML tags.
If you want to render the @
symbol, you need to escape it with another @
symbol:
<p>Email enquiries@@domain.com</p>
Comments can be included in markup or code blocks using standard HTML comment delimiters <!-- -->
or the Razor specific comment delimiters @* *@
:
@{
<!-- A comment -->
@* Another comment *@
}
<!-- A comment -->
@* Another comment *@
Blazor Specifics
In Blazor components, the content of code blocks @{ ... }
are included in the body of the component's BuildRenderTree
method and evaluated/executed as part of that method.
Component members (fields, properties, methods etc) can be declared in a block that begins with @code {
and ends with }
. The content within the @code
block is pure C#:
@code {
string message { get; set; }
void setMessage(){
message = "Hello World";
}
}
In pre-release versions of Blazor, @functions
was used to encapsulate blocks of C# code instead of @code
. The @functions
directive is still supported. You can include multiple @code
and/or @functions
blocks in a single Razor component.
Comments are not included in the rendered output of a Razor component, unlike Razor Pages, where comments placed in the HTML comment tags <!-- -->
are rendered, regardless whether they are used in markup or within a code block.
Raw HTML
Asa security measure, Razor output is HTML-encoded by default. Sometimes, you will want to render content as HTML. To do this, you cast the content to a MarkupString
:
var html = "<p>This is a paragraph</p>";
@((MarkupString)html)
You may need to do this, for example, to replace line breaks in data stored in a database with their HTML equivalents:
@(MarkupString)s.Replace(Environment.NewLine, "<br />")
Razor Templates
Razor templates provide a way to define reusable snippets of UI comprising of both HTML and C# within a code block, such as the @code
section. Razor templates are assigned to the RenderFragment
delegate:
@code {
RenderFragment time = @<p>@DateTime.Now.ToLongTimeString()</p>;
}
They are rendered within the component using the usual rendering syntax:
@time
A second version of the RenderFragment
delegate takes a generic parameter representing a type to be passed in to the template:
@code {
RenderFragment<Book> bookDetails = (book) => @<div>
<p>@book.Title</p>
<p>@book.Author.Name</p>
</div>;
}