TOC

The community is working on translating this tutorial into Chinese, but it seems that no one has started the translation process for this article yet. If you can help us, then please click "More info".

Razor:

Templated delegates

The templated delegates functionality in Razor allows you to define a piece of markup and then have it used to represent a specific object on the page. This is a great tool when you need to represent e.g. one of your classes in multiple places inside of your View. It can also be a great way to separate a large chunk of markup from the logic of your View which can make it easier to read and maintain large Views.

When defining a templated delegate, you will be using a Func delegate - it could look like this:

Func<dynamic, object> movieTemplate = @<div>@item.Title [@item.ReleaseDate.ToShortDateString()]</div>;

In this first half, before the equal-sign, I create the movieTemplate delegate. In the second part, I specify the markup template to be used. Notice that I use a variable called item - it's passed into the delegate and the type is dynamic, meaning that I can access members on it (e.g. Title) which are not checked at compile-time. Instead, they are validated at runtime, where they are expected to exist on the object passed to the delegate - if not, an exception will be thrown! I intend on passing in objects of the type Movie, a simple class we used previously in this tutorial:

public class Movie
{
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
}

So, with our templated delegate in place, we can now use it, e.g. inside a loop. Notice how I can now just call the delegate and pass in the Movie object, instead of defining the markup inside the loop:

@foreach(var movie in movies)
{
    @movieTemplate(movie)
}

When populating the movies collection, used in the loop, with some test data, the generated output will look like this:

<div>The Godfather [24-03-1972]</div>
<div>Forrest Gump [06-07-1994]</div>
<div>Fight Club [15-10-1999]</div>

And here's a complete example, including test data about movies, for you to experiment with:

@using HelloMVCWorld.Models
@{
    ViewData["Title"] = "TemplatedDelegate";

    Func<dynamic, object> movieTemplate = @<div>@item.Title [@item.ReleaseDate.ToShortDateString()]</div>;

    List<Movie> movies = new List<Movie>();
    movies.Add(new Movie() { Title = "The Godfather", ReleaseDate = new DateTime(1972, 3, 24) });
    movies.Add(new Movie() { Title = "Forrest Gump", ReleaseDate = new DateTime(1994, 7, 6) });
    movies.Add(new Movie() { Title = "Fight Club", ReleaseDate = new DateTime(1999, 10, 15) });

}

@foreach(var movie in movies)
{
    @movieTemplate(movie)
}

Summary

The templated delegates syntax found in Razor makes it easy for you to define markup-based templates which can be re-used in multiple places in your Views.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!