Custom Hidden HTML Helper with Model Binding in MVC3 Razor

  1. In MVC3 Razor we have HTML helpers to render different controls. 
  2. Instead of using these helpers we can create our own helper classes and methods and use them as we want.
  3. The creation of custom helpers provides flexibility to change the attributes and style of the control that renders.
  4. In this article we will create Custom HTML helper for input type hidden with Model Binding to render textbox of type hidden.

Following are the steps :

We have created a separate folder named CustomHelpers to hold Custom HTML Helpers. We have created a class named CustomHiddenHelperModelBinding.cs which will contain code to render hidden input field.

The class file looks like below :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Linq.Expressions;

namespace CustomHtmlHelpers.CustomHelpers
{
    public static class CustomHiddenHelperModelBinding
    {
        //This overload accepts single expression as parameter.
        public static MvcHtmlString Custom_HiddenFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
        {
            return Custom_HiddenFor(helper, expression, null);
        }

        //This overload accepts expression and htmlAttributes object as parameter.
        public static MvcHtmlString Custom_HiddenFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
        {
            //Fetching the metadata related to expression. This includes name of the property, model value of the property as well.
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            //Fetching the property name.
            string propertyName = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();

            //Creating a textarea tag using TagBuilder class.
            TagBuilder hidden = new TagBuilder("input");

            //Setting the type attribute to hidden to render hidden input field.
            hidden.Attributes.Add("type", "hidden");

            //Setting the name and id attribute.
            hidden.Attributes.Add("name", propertyName);
            hidden.Attributes.Add("id", propertyName);

            //Setting the value attribute of textbox with model value if present.
            if (metadata.Model != null)
            {
                hidden.Attributes.Add("value", metadata.Model.ToString());
            }
            //merging any htmlAttributes passed.
            hidden.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            return MvcHtmlString.Create(hidden.ToString(TagRenderMode.Normal));
        }
    }
}

Overload 1 : The first overload accepts linq expression as parameter. This method is extension method and accepts object of HtmlHelper class. The first parameter adds this overload to System.Web.MVC namespace. On view we can access this method using @html. This overload in turn calls another overload.

Overload 2 : The second overload accepts linq expression and htmlAttributes object as parameters. We have use ModelMetaData class to get all details or meta data about the expression. We get the property name and model value using ModelMetaData class.

The propertyName is used to set the name attribute of the control. We have used TagBuilder class to create input element. We have set type property to hidden to render hidden input field.
          We have also assigned other attributes passed using htmlAttributes object. The Model value is fetched if present and assigned to hidden input's value attribute. The entire control is returned as MVCHtmlString format.

ViewModel :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;


namespace CustomHtmlHelpers.Models
{
    public class Register
    {
        public string hidden { get; set; }
    }
}

We have created a hidden property in our View Model. We will bind this View Model to our view. On View we will bind this property to our control.

Controller :



public ActionResult About()
        {
            Register register = new Register();
            register.hidden = "Fabregas";
            return View(register);
        }

In the controller, we are creating object of our ViewModel class and assigning value to the hidden property. We will pass this model to the View. View will render the control. The value passed will be shown with the control.

View :



<h2>About</h2>
<div>
@Html.Custom_HiddenFor(Model => Model.hidden)
@Html.Custom_HiddenFor(Model => Model.hidden, new { @class = "hiddenClass" })
</div>

Rendered HTML :


<h2>About</h2>
<div>
<input id="hidden" name="hidden" type="hidden" value="Fabregas"></input>
<input class="hiddenClass" id="hidden" name="hidden" type="hidden" value="Fabregas"></input>
</div>

Thus following the above steps we can create our own custom helper for input type="password". We can customize more as per our requirement.

0 comments:

Post a Comment