自訂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.GetExpressionText與ModelMetadata.FromLambdaExpression,可以快速從Expression取得name跟value,這樣就不用使用原本Expression的方式來取得值,程式碼簡潔很多。
參考
http://dan.cx/2012/05/custom-strongly-typed-htmlhelpers-in-asp-net-mvc
一天一分享,身體好健康。
該追究的不是過去的原因,而是現在的目的。