Table of contents

Last updated .

< Previous chapterNext chapter >

Using the Razor view engine

MVC views are constructed as Razor views. The result is a file containing html interspersed with Razor statements and expressions. The html need not be a complete html document, it may also be a HTML fragment. Razor view files are recognized by their .cshtml extension. The file is not compiled it is needed at runtime. This has the downside that you will sometimes not catch errors until you run the application, but has the benefit that you can edit the view file and see immediate results. There is no need to shut down the app, correct the error and start it again. You can just fix the error in the view file and then hit F5 in the browser to see the result of the change.

Building on the sample application from the last chapter, I have deliberately made a typo in the index.cshtml file (the startup page), typing "Shame" instead of "Name":

Error in Razor file
Error in Razor file

Note that the code editor clearly shows there is a problem, as indicated by the red wavy line. Nevertheless, you can start debugging the app by presssing F5 with no problem. If you do that, you'll just see a blank page in the browser. The problem is that, by default, ASP.Net will not write error information to the response. To enable that while developing (but not for a production environment), we need to add this configuration to the Configure method of the Startup class:

Startup.cs (partial)
..... if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } .....

This configuration makes ASP.Net output some exception information to the response. When you add this code, you'll need to install a package, as shown in the pop-up message:

Install package Microsoft Asp.Net Diagnostics
Install package Microsoft Asp.Net Diagnostics

Just click on the yellow bar reading "Add package Microsoft..." to add the required package.

Now, the browser view clearly tells you of the problem in the Razor view file:

Error info in the diagnostic page
Error info in the diagnostic page

Razor syntax


A Razor expression is recognized by the starting "@" character. This character denotes that .Net code is what follows, not markup. As an example consider the code <title>@ViewBag.Title</title>. It starts with an HTML tag, then a Razor statement and then a closing HTML tag. Notice there is no explicit termination of the Razor statement. The Razor engine is usually smart enough to work out that some text is not code (in this example </title>) and so implicitly terminates the statement. Sometimes, though, the parser needs a little help to find out which is which. In that case, you can disambiguate things by wrapping the entire code block in parentheses. For example, the previous statement can be rewritten as <title>@(ViewBag.Title)</title>.

Code blocks

Notice in the above examples, there are no semicolons to terminate the code statement. So what if you need more than one line of code in a given place? Use a code block. A code block is is recognized by wrapping curly parentheses, as in this example:

@{ string message = "Time is "; message += DateTime.Now.ToString(); } <p>@message</p>

The above example also shows how to declare and use variables in Razor. The variable is then in scope throughout the file.


Loops are constructed using the well-known constructs, for example:

@for (int x = 0; x < 3; x++) { <li>@x</li> }

Note that the curly braces are mandatory. Aften the opening brace, the context switches from code to markup.

Conditional statements

Again, conditional statements follow the same pattern as for iteration:

@{ bool condition = true; } @if (condition) { <p>Yes!</p> }

Mixing code and text

The result of an expression is automatically html-encoded. An example:

@{ bool condition = true; string message = "<p>Hello</p>"; } @if (condition) { <p>@message</p> }

When shown in the browser, the output from the above example reads "<p>Hello</p>". After the opening brace, Razor expects an HTML tag. If you want to render some literal (and unencoded) text instead, you can use this syntax:

@{ bool condition = true; } @if (condition) { @:Hello from here! }

Escaping @

If you need to display the @ character as part of some literal text, you escape it by doubling it, for example:

<p>@@ is the 'at' character</p>

Note, however, that Razor recognizes email addresses, so the @ needs no escaping in that case:

<p>My email is</p>

Razor and html attributes

In relation to attributes, where a Razor expression is used to generate the value of the attribute, there is some special behaviour. If the expression evaluates to null, the attribute is not rendered:

@{ string url = null; } <a href="@url">My link</a>

In the above example, the anchor tag has no resulting href attribute because the expression for the attribute value evaluates to null. With custom data- attributes, it is a little different. For those, an expression evaluating to null will result in an empty string for the attribute value.

For those HTML attributes that really are booleans, Razor omits the attribute if the expression evaluates to null. For example:

@{ bool isChecked = false; } <input type="checkbox" checked="@isChecked" />

The above example results in the markup <input type="checkbox" /> for the checkbox. Had the expression evaluated to true, the markup would have been <input type="checkbox" checked="checked" />.

The @model statement

A strongly typed view is created when a @model statement is added to a view. The statement declares the type of the datamodel object, which is set by the controller prior to rendering the view. When the model object type has been declared in the view, it is referred to in code with the keyword Model or with @Model as an expression, as in this example, employing a Contact class:

@model Contact[] <ul> @foreach (Contact contact in Model) { <li>@contact.Name: @contact.Email</li> } </ul> <p>@Model.Count() contacts</p>

The @using statement

Namespaces can be brought into scope with a @using statement. It works in the same way as a using statement in a "normal" C# file, as in this example:

@using MVCTutorial.Models

< Previous chapterNext : The MVC URL Routing >

2016 by Niels Hede Pedersen Linked in