Razor Template in ASP.NET MVC 3
Update: There is no need to inherit _ViewStart view class with ViewStartPageWithHelpers in ASP.NET MVC 3 RTM.
Introduction:
Templates are used to display a predetermined portion of the page layout which also contains fill-in-the-blanks that can be filled at run time. Template saves a lot of time because it can be reused in many places. Razor view engine includes a feature called Inline Template which allows you to define a portion of dynamic HTML that can reused. Also using Razor template you can pass template as a parameter to a method. In this article I will show you how to use Razor template in ASP.NET MVC. I will also show you how you can define an inline Razor template once and then reuse this template in your application.
Description:
Let's say that you need to show all student's Name and Age in many places in your application. First of all create a new MVC 3 Project. Now create a new class file Student.cs inside Model folder and add the following code,
public class Student { public string Name { get; set; } public int Age { get; set; } public static List<Student> CreateTestStudents() { List<Student> students = new List<Student>(); for (int i = 1; i <= 10; i++) { Student student = new Student() { Age=25+i, Name="Student "+i }; students.Add(student); } return students; } }
This is a simple Student class with Name and Age properties. It also includes a static method which is used for creating and returning some students for the testing purpose.
Now we need to put the template so that it can be reused all over the application. I think _ViewStart.cshtml file is the best place to put this template. Because code inside _ViewStart.cshtml file runs before any view run. So just open _ViewStart.cshtml file and add the following code,
@inherits ViewStartPageWithHelpers @{ Layout = "~/Views/Shared/_Layout.cshtml"; Func<List<Student>,HelperResult> h = @<table> <tr> <th align="center"> Student Name: </th> <th align="center"> Student Age: </th> </tr> @foreach (var itm in item) { <tr> <td align="center"> @itm.Name </td> <td align="center"> @itm.Age </td> </tr> } </table>; ViewContext.Controller.ViewData["StudentsTemplate"]=h; }
You can create an inline template in Razor by using @<tag>...</tag> syntax. The above code simply create an inline template which contains a table layout showing all students Name and Age. Note here that the template always return a delegate of type Func<T,HelperResult> where T is a Place Holder for a any defined type. Here I am using List<Student> for T type. You can use item parameter in your inline template which is of type T(in this case List<Student>). The view which calls this delegate method is responsible for sending this parameter. Next I am simply saving this delegate to ViewContext.Controller.ViewData so that it will be reused in any view.
Also note that I am inheriting the _ViewStart view class with ViewStartPageWithHelpers class. The reason for inheriting with this new class is that there is a bug in ViewStartPage class. The bug is that the WriteLiteralTo and WriteTo methods are absent in ViewStartPage class. This custom class will fill this gap by adding these methods. According to Andrew Nurse(ASP.NET team member), this bug will be fixed in RTM. So no need for doing this in ASP.NET MVC 3 RTM. So let's create a new class file ViewStartPageWithHelpers.cs inside Helper folder and add the following code,
public abstract class ViewStartPageWithHelpers : ViewStartPage { public static void WriteLiteralTo(TextWriter writer, object content) { writer.Write(content); } public static void WriteTo(TextWriter writer, object content) { writer.Write(HttpUtility.HtmlEncode(content)); } }
Now let's see how to use this inline template in your view. First of all just open HomeController.cs and add the following code,
public class HomeController : Controller { public ActionResult Index() { return View(Student.CreateTestStudents()); } }
The above code simply add a Index action with List<Student> Model. Next add a view for Index action and add the following lines inside this view,
@model List<Student> @{ View.Title = "Home Page"; Func<List<Student>,HelperResult> lst = ViewContext.Controller.ViewData["StudentsTemplate"] as Func<List<Student>,HelperResult>; } @lst(Model)
In this view first of all I am setting the Model for this view as List<Student>. Next I am retrieving the delegate from ViewContext.Controller.ViewData which was saved in _ViewStart.cshtml file. Finally, I am invoking the delegate method and passing the Model as parameter. Now just run this application. You will find the following screen,
Now you can reuse this code in any view where you need to show all the students Name and Age.
Summary:
In this article I showed you how you can use Razor Inline Template in your ASP.NET MVC project. I explained you with example. I also showed you how you can define the inline template once and then reuse it all over in your application. Don't forget to download the sample application. Hopefully you will enjoy this article too.