[MVC][C#]自訂強型別Html Helper

  • 1607
  • 0
  • MVC
  • 2016-12-30

自訂Html Helper

前言

舊系統的一些資料表欄位將判斷 [是] 或 [否] 的欄位設為 nvarchar,使用"1"代表是、"0"代表否。  這時候要使用Html Helper CheckBoxFor沒有辦法直接用,因為MVC內建的CheckboxFor只能使用bool,所以只好自訂一個產生出字串的CheckBoxFor。

範例如下:

public static class CheckBoxHelperExtension
{
    public static MvcHtmlString CheckBoxByStringFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, string>> expression, object htmlAttributes = null)
    {
        var name = ExpressionHelper.GetExpressionText(expression);
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        var value = metadata.Model;

        var checkboxBuilder = new TagBuilder("input");
        checkboxBuilder.GenerateId(name);

        checkboxBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.CheckBox));
        checkboxBuilder.MergeAttribute("name", name);
        checkboxBuilder.MergeAttribute("value", "1");

        if (value.ToString() == "1")
        {
            //Note : Attributes.Add 實際上也是呼叫 MergeAttribute,差別在於沒有設定MergeAttribute 的 replaceExisting參數
            checkboxBuilder.Attributes.Add("checked", "checked");
        }

        RouteValueDictionary attr = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        checkboxBuilder.MergeAttributes(attr);

        //若checkbox沒有打勾,要取得0的值,所以需要多一個hidden input
        var hiddenBuilder = new TagBuilder("input");

        hiddenBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
        hiddenBuilder.MergeAttribute("name", name);
        hiddenBuilder.MergeAttribute("value", "0");

        //checkbox + hidden 輸出
        string result = checkboxBuilder.ToString(TagRenderMode.SelfClosing) + hiddenBuilder.ToString(TagRenderMode.SelfClosing);

        return MvcHtmlString.Create(result);
    }
}

 

小結

MVC有提供一些方法ExpressionHelper.GetExpressionTextModelMetadata.FromLambdaExpression,可以快速從Expression取得name跟value,這樣就不用使用原本Expression的方式來取得值,程式碼簡潔很多。

 

參考

http://dan.cx/2012/05/custom-strongly-typed-htmlhelpers-in-asp-net-mvc

https://www.asp.net/mvc/overview/older-versions-1/views/using-the-tagbuilder-class-to-build-html-helpers-cs

 

 

一天一分享,身體好健康。

該追究的不是過去的原因,而是現在的目的。