Quick Tips About ASP.NET MVC – Editor Templates

Quick Tips About ASP.NET MVC – Editor Templates

In the last quick tip, I showed off how you can use the UIHint data annotation to specify a custom template for rendering of a particular field. An important part of that mechanism is the DisplayFor strongly-typed html helper that was introduced in ASP.NET MVC 2.

As mentioned before, we can also use the EditorFor html helper to format the rendering of a field in an Edit view. In this example, we will use the model we created in the last tip:

publicclassAuthor

{

publicstring Name { get; set; }

publicstring Email { get; set; }

[UIHint("Avatar")]

publicstring Avatar { get; set; }

publicbool Active { get; set; }

}

publicclassPost

{

publicstring Title { get; set; }

publicstring Body { get; set; }

publicstring Rating { get; set; }

publicDateTime Date { get; set; }

publicAuthor AuthorInfo { get; set; }

}

Let’s start off by modifying our Index action method in the Home Controller, in order to display an Edit view for the Post class:

publicActionResult Index()

{

Post post = newPost();

post.Title = "ASP.NET Quick Tip #1";

post.Body = "Some awesome tip";

post.Date = System.DateTime.Now;

post.Rating = "Excellent";

return View("Edit",post);

}

Next step, we ask Visual Studio to generate a strongly-typed view for the Post class, and choose the Edit template (according to this code, we need to name the view ‘Edit’):

The default rendering for edit views is pretty much placing everything inside Textboxes. However, as you saw in the previous tip, we can override this by using templates. In this particular case, we’re interested in making it easier to edit the Rating field. Instead of asking the user to type the value, we want to display a drop down list of predefined values to choose from.

But first, we have to prepare our view so that it “listens” to the templates. Change the rendering of the Rating field to this:

<p>

<labelfor="Rating">Rating:</label>

<%= Html.EditorFor(model => model.Rating) %>

<%= Html.ValidationMessage("Rating", "*") %>

</p>

Notice that, in this case, I’m using the EditorFor html helper to render the field. If you launch your application now, everything will be the same as the Rating field is simply a string, so it gets the default rendering.

Let’s create our template first: add a EditorTemplates folder under the Views for the Home Controller:

Inside the EditorTemplates folder, create a Partial view as we did in the last Quick Tip, and name it RatingsDropDown. Place the following code in the partial view:

This will generate a drop down list, using these hardcoded values, and also sets the current selected option to our Model value.

Using Data Annotations, we can now enrich our model by stating that the Rating field should be rendered (when possible) as a RatingsDropDown:

[UIHint("RatingsDropDown")]

publicstring Rating { get; set; }

If we now launch our application, we will now be presented with this:

So, the EditorFor html helper realized there was a template called RatingsDropDown and followed our data annotation for this field, allowing us to create a better experience for our users. And, if we need to display this field in another view (also in edit mode) we will get the same experience automatically. Pretty cool stuff!

Every time I show off this demo I get a question: how can we avoid hardcoding the dropdown list values in the template? Well, like everything else in ASP.NET MVC, if you want to display information, you have to find a way to pass it on to your view.

Let me change the Index method to add that information to the view:

publicenumRatings { Excellent, Good, Average, Poor, Awful };

publicActionResult Index()

{

Post post = newPost();

post.Title = "ASP.NET Quick Tip #1";

post.Body = "Some awesome tip";

post.Date = System.DateTime.Now;

post.Rating = "Excellent";

ViewData["Ratings"] = Enum.GetNames(typeof(Ratings));

return View("Edit",post);

}

In this case, we are using an enum type to specify the values we want, which is a very common approach to make coding easier. We are passing all the values defined in the enum to our view using the ViewData dictionary (notice I added a new value).