Friday, February 5, 2010

ASP.NET MVC2 - Creating a Display Template

By Hristo Yankov
ASP.NET MVC philosophy is "Skinny Controller, Fat Model, Stupid View". The focus of today's post is "stupid view". What does this mean? Well, it means that you should avoid writing any logic in your views. A view should be as simple as wrapping the model's properties in html tags.

If you are cornered, and must have some kind of a login in your view, it would be nice if it is neatly wrapped in a DisplayTemplate, so your code remains reusable, easy to read and maintain. What follows now is a tutorial on how to create one.

Problem: We have a Model which has a property "RemainingTime", which is an integer and represents the estimated remaining seconds of some operation. We want to neatly format this time in the view, so that if it has a value of, let's say, "5", to be displayed as "5 seconds". If it has value of "70", to be displayed as "1 min, 10 seconds", etc...

Solution: Create a reusable DisplayTemplate and use it to visualize the property.

We start by creating a new ASP.NET MVC2 "empty" project template. We don't need the default authentication and home controllers, so that would do just fine.

As a first step, let's create our Model. We'll call it "RemainingTimeModel" and will have the integer property "EstimatedSeconds". We will name the DisplayTemplate "SecondsFormatting". So we go ahead and decorate the "EstimatedSeconds" property with the UIHint attribute, passing "SecondsFormatting" (which is the name of the DisplayTemplate we want to use) in its constructor. This attribute tells ASP.NET MVC which DisplayTemplate to use by default, for this property. Your code should look like this:

Second step is to create the actual DisplayTemplate. It needs to reside in the "Views/Shared/DisplayTemplates" folder, and be named "SecondsFormatting.ascx". So, create a "DisplayTemplates" folder in your Shared views, then right click it and Add -> View. Check the 'create partial view' checkbox and give it the name we mentioned above. By default, this will create non-strongly typed ViewUserControl. We will extend this, to an integer. Open the "SecondsFormatting.ascx" file and change the Inherits="System.Web.Mvc.ViewUserControl" to Inherits="System.Web.Mvc.ViewUserControl". Now, when you refer to the Model object in this control, you are working with an integer. The Model that will be passed to this DisplayTemplate is the "EstimatedSeconds" property of the "RemainingTimeModel" model.

Now we just need to implement some logic in the control. Let's do this:

Ok, we have the model, which has the seconds property, and we have a DisplayTemplate for it. Now we jsut need to use it. For this purpose, we will create one simple controller, which creates a new instance of the model and initializes it, then passes the model to a view. In the view, we will have: Html.DisplayFor(model => model.EstimatedSeconds). Like that:



See how clean your View remains? No logic in there, just a DisplayFor html helper call.

We can now go ahead and try it out, with a couple of different values. It formats it accordingly. Please note that there are much easier ways to format the time and it was used here just as an example of what we should do if our view requires to have a logic. If we try with 3732 seconds, it should display "1 hours, 2 minutes, 12 seconds".

Now you know how to encapsulate your logic in DisplayTemplates and keep your main Views clean and neat.

You can download the demo project from here.
Bookmark and Share

No comments: