Custom Password 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 Password with Model Binding to render textbox of type password.

Following are the steps :

We have created a separate folder named CustomHelpers to hold Custom HTML Helpers. We have created a class named CustomPasswordHelperModelBinding.cs which will contain code to render password control.

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 CustomPasswordHelperModelBinding
    {
        //This overload accepts single expression as parameter.
        public static MvcHtmlString Custom_PasswordFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
        {
            return Custom_PasswordFor(helper, expression, null);
        }

        //This overload accepts expression and htmlAttributes object as parameter.
        public static MvcHtmlString Custom_PasswordFor<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 password = new TagBuilder("input");
            password.Attributes.Add("type", "password");
            //Setting the name and id attribute.
            password.Attributes.Add("name", propertyName);
            password.Attributes.Add("id", propertyName);

            //Setting the value attribute of textbox with model value if present.
            if (metadata.Model != null)
            {
                password.Attributes.Add("value", metadata.Model.ToString());
            }
            //merging any htmlAttributes passed.
            password.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            return MvcHtmlString.Create(password.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 password to render password.
          We have also assigned other attributes passed using htmlAttributes object. The Model value is fetched if present and assigned to textarea's innerHtml property. 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 password { get; set; }
    }
}

We have created a password 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.password = "Fabregas";
            return View(register);
        }

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

View :



@model CustomHtmlHelpers.Models.Register

@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<div>
@Html.Custom_PasswordFor(Model => Model.password)
@Html.Custom_PasswordFor(Model => Model.password, new { maxlength = 10})
</div>

In the View, we have binded the ViewModel. We have used our Custom helper to render the control for password property. We have binded the control to password property using linq expression.

UI :



The password control is rendered as expected. The additional attributes passed using htmlAttributes for second control are applied.


Rendered HTML :



<h2>About</h2>
<div>
<input id="password" name="password" type="password" value="Fabregas"></input>
<input id="password" maxlength="10" name="password" style="color:Red;" type="password" 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