Centralizing display logic with templated helpers

In this recipe, we are going to look at how we can get some reuse out of our display code by using templated helpers.

Getting ready

To continue our e-commerce example, we are going to look at how to control the format of bits of our Product class from the previous recipe. Specifically, we will take a look at how to centralize the display of our product's cost.

How to do it...

  1. First, we need to go into the Views/Home folder and create a new folder called DisplayTemplates.
  2. Next, we need to create a partial view that will hold the display logic for the product's cost property. Right-click on the DisplayTemplates folder in the Views/Home folder and select Add View.
  3. Name your view Product.Cost and then select the Create a partial view (.ascx) checkbox.

    Note

    You can call this control whatever you like. You will reference the name you choose directly in an upcoming step.

  4. Now open up your new partial view and add some code to format the cost of a product (a Double). The Model reference in this code will be whatever value you feed this snippet later.

    Views/Home/DisplayTemplates/Product.Cost.ascx:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
    <%= String.Format("{0:C}", Model)%>
    
  5. Now open up your Product.aspx view page. Under the place where the ProductName is currently displayed, we will display the Cost property and specify with a hint which template we want to use.

    Views/Home/Product.aspx:

    <h2><%= Model.CurrentCategory.Name %></h2>
    <%= Model.CurrentProduct.ProductName %>
    <%= Html.DisplayFor(Double=>Model.CurrentProduct.Cost, "Product.Cost") %>
    
  6. Hit F5 and see your cost property formatted appropriately!
    How to do it...

How it works...

The rendering engine noticed your hint of Product.Cost. It then looked in the DisplayTemplates folder to see if there were any templates with the same name as the Product.Cost hint. When it found the Product.Cost.ascx partial view, the call to Html.DisplayFor used the partial view to render the property.

Notice that in the DisplayFor method we used a lambda expression to pass only the Cost property (a Double) to the partial view. This is the only sticky part of how these templates work. The caller needs to know what the partial view expects.

There's more...

There are a few other things to know about templated helpers. Rather than using hints to specify how you want to render things, you could instead build templates based purely on data types. Also, you don't have to put the DisplayTemplates folder in the Home view subdirectory. You could instead create a template for usage by a view in any of the view folders. And if you did want to use hints but didn't want to specify them in the presentation code, that can be done too!

Type-specific templated helpers

Templated helpers, by default, can be based on the data type that is passed into the Html.DisplayFor method. If you were to create a Double.ascx partial view and place it in the DisplayTemplates folder and you then passed in the Cost property to the DisplayFor method, it would have worked just as well. Expand this thought to creating a template for the Product type and this can quickly simplify the creation of a website!

Where to put the DisplayTemplates folder?

The DisplayTemplates folder can be in both a specific view folder or in the shared folder. The DisplayFor method will first look in the current controller's corresponding view folder for any appropriate DisplayTemplates folder. If it doesn't find an appropriate partial view for the current rendering, it will look to the shared folder for an appropriate display template.

DataAnnotations on your model to specify UIHints

To utilize this method, the mechanics of using the Html.DisplayFor and the creation of the partial view in a DisplayTemplates folder are identical as mentioned earlier. The only thing different here is that you would specify a UIHint attribute on the Product class like this:

[UIHint("Product.Cost")]
public Double Cost { get; set; }

I am not a big fan of this particular method though; I think that it puts concerns in the wrong places (formatting code shouldn't be specified with your business objects). You could use this method on your ViewModel though, depending on where you specify it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset