Click here to Skip to main content
15,867,453 members
Articles / Web Development / ASP.NET
Tip/Trick

Custom Strongly-typed HtmlHelpers in ASP.NET MVC

Rate me:
Please Sign up or sign in to vote.
4.90/5 (11 votes)
22 May 2012CPOL2 min read 61.9K   24   8
Custom strongly typed HtmlHelpers in ASP.NET MVC

Background

The original release of ASP.NET MVC used HTML helpers with a syntax like the following:

C#
@Html.TextArea("Title") 

These worked, but if you renamed the property in your model (for example, from “Title” to “Subject”) and forgot to update your view, you wouldn’t catch this error until you actually tried out the page and noticed your model isn’t populating properly. By this time, you might have users using the site and wondering why stuff isn’t working.

ASP.NET MVC 2 introduced the concept of strongly-typed HtmlHelper extensions, and ASP.NET MVC 3 extended this even further. An example of a strongly typed HtmlHelper is the following:

ASP.NET
@Html.TextAreaFor(post => post.Title)

These allow you to write more reliable code, as view compilation will fail if you change the field name in your model class but forget to change the field name in the view. If you use precompiled views, this error will be caught before deployment.

Creating your Own

The built-in helpers are good, but quite often it’s nice to create your own helpers (for example, if you have your own custom controls like a star rating control or rich-text editor). These new helpers are very easy to create, since we can make use of two different classes that come with ASP.NET MVC:

  • ExpressionHelper — Gets the model name from a lambda expression (for example, returns the string Date” for the expression post => post.Date, and “Author.Email” for the expression post => post.Author.Email). This is what you’d use in the ID and name of the field
  • ModelMetadata — Gets other information about the lambda expression, including its value

These two classes give us all the information we require to make our own HTML helpers (internally, these are what all the built-in strongly-typed HTML helpers use).

Here’s an example of a simple HTML helper that uses both of the above classes:

C#
public static MvcHtmlString NewTextBox(this HtmlHelper htmlHelper, string name, string value)
{
	var builder = new TagBuilder("input");
	builder.Attributes["type"] = "text";
	builder.Attributes["name"] = name;
	builder.Attributes["value"] = value;
	return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
}

public static MvcHtmlString NewTextBoxFor<TModel, TProperty>
(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
	var name = ExpressionHelper.GetExpressionText(expression);
	var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
	return NewTextBox(htmlHelper, name, metadata.Model as string);
}

Given a model like this:

C#
public class Post
{
	public string Title { get; set; }
	// ...
}

A view like this:

C#
@Html.NewTextBoxFor(model => model.Title)

Will produce HTML like this:

HTML
<input name="Title" type="text" value="" />

Obviously this isn't the most useful example, but you can extend this pattern to create whatever control you like. For helpers with larger chunks of HTML, I’d suggest using partial views. These can be rendered using htmlHelper.Partial().

Hopefully this helps someone!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer Facebook
United States United States
I'm a web developer specialising in ASP.NET MVC, PHP and JavaScript. I've got several years of web development experience and am always trying new technologies.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Ehsan Sajjad26-Jan-17 10:10
professionalEhsan Sajjad26-Jan-17 10:10 
GeneralExactly what I was looking for! Pin
Bananatie7-Oct-15 23:25
Bananatie7-Oct-15 23:25 
QuestionSimple Pin
Assil20-Jun-14 1:45
professionalAssil20-Jun-14 1:45 
QuestionThanks a lot Pin
Bret Williams9-Aug-12 2:43
Bret Williams9-Aug-12 2:43 
QuestionInteresting but how would I do this Pin
RickNash26-Jun-12 5:27
RickNash26-Jun-12 5:27 
GeneralRe: Interesting but how would I do this Pin
Daniel Lo Nigro30-Jun-12 16:36
Daniel Lo Nigro30-Jun-12 16:36 
GeneralMy vote of 5 Pin
Howard Richards15-Jun-12 0:59
Howard Richards15-Jun-12 0:59 
GeneralRe: My vote of 5 Pin
Daniel Lo Nigro30-Jun-12 16:38
Daniel Lo Nigro30-Jun-12 16:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.