This post is largely based off of Phil Haack’s article titled Templated Razor Delegates. I strongly recommend reading this article first. Here’s a sample code for the same, so you can have a look at. I also have a custom type being rendered as a table. 1: // my custom type
2: public class Device
3: {
4: public int Id { get; set; }
5: public string Name { get; set; }
6: public DateTime MfgDate { get; set; }
7: }
Now I can write an extension method just for this type.
1: public static class RazorExtensions
2: {
3: public static HelperResult List(this IList<Models.Device> devices, Func<Models.Device, HelperResult> template)
4: {
5: return new HelperResult(writer =>
6: {
7: foreach (var device in devices)
8: {
9: template(device).WriteTo(writer);
10: }
11: });
12: }
13: // ...
14: }
Modified my view to make it a strongly typed one and included html to render my custom type collection in a table.
1: @using TemplatedRazorDelegates
2: @model System.Collections.Generic.IList<TemplatedRazorDelegates.Models.Device>
3:
4: @{
5: ViewBag.Title = "Home Page";
6: }
7:
8: <h2>@ViewBag.Message</h2>
9:
10: @{
11: var items = new[] { "one", "two", "three" };
12: IList<int> ints = new List<int> { 1, 2, 3 };
13: }
14:
15: <ul>
16: @items.List(@<li>@item</li>)
17: </ul>
18: <ul>
19: @ints.List(@<li>@item</li>)
20: </ul>
21:
22: <table>
23: <tr><th>Id</th><th>Name</th><th>Mfg Date</th></tr>
24: @Model.List(@<tr><td>@item.Id</td><td>@item.Name</td><td>@item.MfgDate.ToShortDateString()</td></tr>)
25: </table>
We get intellisense as well!
Just added some items in the action method of the controller:
1: public ActionResult Index()
2: {
3: ViewBag.Message = "Welcome to ASP.NET MVC!";
4: IList<Device> devices = new List<Device>
5: {
6: new Device {Id = 1, Name = "abc", MfgDate = new DateTime(2001, 10, 19)},
7: new Device {Id = 2, Name = "def", MfgDate = new DateTime(2011, 1, 1)},
8: new Device {Id = 3, Name = "ghi", MfgDate = new DateTime(2003, 3, 15)},
9: new Device {Id = 4, Name = "jkl", MfgDate = new DateTime(2007, 6, 6)}
10: };
11: return View(devices);
12: }
Running this I get the output as:
Absolutely brilliant! Thanks to both Phil Haack and to David Fowler for bringing this out to us. Download the code for this from here.
Verdict: RazorViewEngine.Points += 1;