How to create custom HTML Helpers for ASP.NET MVC 3 and Razor View Engine

5 Mar
2011

I will try to show you a basic feature of ASP.NET MVC, creating custom HTML Helpers. We can reduce the amount of logic in view pages (razor or asp.net –aspx- pages) by extracting logic code as method.

HTML Helper methods are nothing more than methods that are returning string. If you want to write your own Html Helper method you have to write extension methods for HtmlHelper class. ASP.NET MVC Framework itself contains extension methods for HtmlHelper class to have well structured helper methods separation. ASP.NET MVC Framework Html Helper extension methods are located under System.Web.Mvc.Html namespace.

How to write your own Html Helper methods?

Razor pages uses System.Web.Mvc.WebViewPage type as base class. Razor pages automatically inherits from this type, If you want to see the configuration or if you want to replace it with your base class you should check web.config file in your ASP.NET MVC project. This subject is not in this article’s context but if you want to use your own base class, you can create a new class which inherits from WebViewPage and you can edit web.config file with your type name.

razor_base_page

I mentioned that Html Helper methods are extension methods for HtmlHelper classes (one is generic, one is plain old class). So, we can write extension methods to use them inside Razor pages but how does it happen?

WebViewPage

As you can see from above screenshot WebViewPage has a property named Html and this property type is System.Web.Mvc.HtmlHelper<T>.

And we can access this type and it’s member from Razor pages. (see below)

html_intellisense

It seems we can add our extension methods and access that methods from Razor page markup. Let’s create our first extension methods. You can add a new class file and write your own extension method, there is no difference than normal C# extension methods.

I created a file named HtmlHelperExtensions.cs and added two basic HTML Helper method.

using System.Web.Mvc;

namespace MvcHtmlHelpers
{
    public static class HtmlHelperExtensions
    {
        private const string Nbsp = "&nbsp;";
        private const string SelectedAttribute = " selected='selected'";

        public static MvcHtmlString NbspIfEmpty(this HtmlHelper helper, string value)
        {
            return new MvcHtmlString(string.IsNullOrEmpty(value) ? Nbsp : value);
        }

        public static MvcHtmlString SelectedIfMatch(this HtmlHelper helper, object expected, object actual)
        {
            return new MvcHtmlString(Equals(expected, actual) ? SelectedAttribute : string.Empty);
        }
    }
}

Two extesion methods, one is NbspIfEmpty, it checks the given value and if it’s empty returns &nbsp; , if it is not returns the given value. Second one is return selected attribute if criteria matches.

Let’s try to use this Html helpers methods from your Razor page. It will not work because we need to add our HTML Helper class to the Razor pages. It is same thing to adding a “using” statement to C# classes to use extension methods. Open your web.config file and add namespace of your new class which contains your extension methods.

<system.web.webPages.razor> 
   <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> 
   <pages pageBaseType="System.Web.Mvc.WebViewPage"> 
     <namespaces> 
       <add namespace="System.Web.Mvc" /> 
       <add namespace="System.Web.Mvc.Ajax" /> 
       <add namespace="System.Web.Mvc.Html" /> 
       <add namespace="System.Web.Routing" /> 
       <add namespace="MvcHtmlHelpers" /> 
     </namespaces> 
   </pages> 
</system.web.webPages.razor> 

I want to show using of second HTML Helper. First select element contains and embedded if statement inside markup which doesn’t seem a good. Right?

<select>
   @foreach (var item in ViewBag.Items)
   {
      <option@if (item.ItemName==ViewBag.SelectedItem)
                   {
                       @MvcHtmlString.Create(" selected='selected'")
                   }>@item.ItemName</option>
   }
</select>

 

If we use our HTML Helper methods to make option element selected markup code seems better. (ViewBag.SelectedItem is an dynamic data for this sample Razor page and comes from controller. If item.ItemName equals this value option element will be selected.

<select>
   @foreach (var item in ViewBag.Items)
   {
      <option@Html.SelectedIfMatch((string)ViewBag.SelectedItem,(string)item.ItemName)>@item.ItemName</option>
   }
</select>

This is a very basic sample for HTML Helpers but you should look for possibilities of extract your logic from Razor pages to HTML Helpers.



10 Responses to How to create custom HTML Helpers for ASP.NET MVC 3 and Razor View Engine

Avatar

» How to Change Base Type of Razor View Engine Pages develoq.net

March 6th, 2011 at 7:20 am

[...] In my previous blog entry (How to create custom HTML Helpers for ASP.NET MVC 3 and Razor View Engine) I mentioned possibility of changing base class type of Razor View Engine. It’s not a new approach for ASP.NET developers, we have been applying same pattern for ASP.NET Web Pages too. [...]

Avatar

Jhonny Nina Veizaga

January 4th, 2012 at 2:38 pm

Thanks, I learned how to use the HtmlHelper now.

Avatar

Hein

February 13th, 2012 at 5:34 pm

Thanks!

Avatar

Trinitron

March 27th, 2012 at 10:58 am

Thanks, thats the first time I understood how to use the HTMLHelper!

Avatar

Bill

June 13th, 2012 at 7:04 pm

Is there a version of this for MVC 3 Razor. This is not working for me. I added the namespace to web.config, but it throws an error when rendering.

Avatar

Gaurang

June 22nd, 2012 at 2:40 pm

Thanks Helped to understand how helper works

Avatar

Douglas

August 14th, 2012 at 6:17 am

Thanks!

Avatar

jameel

September 20th, 2012 at 7:17 am

Good work

Avatar

Curtis

December 5th, 2012 at 3:33 pm

Nice write-up. It worked just fine with MVC 4. I wasn’t sure which web.config to edit at first so I tried them both. Naturally, it was the 2nd one I tried – the one under Views\ :)

Avatar

Jay

December 31st, 2012 at 12:07 pm

Thanks

Comment Form

top