使用模型描述中的title属性创建CheckboxFor MVC帮助程序

时间:2015-05-08 15:46:43

标签: asp.net-mvc html-helper

我创建了一个文本框助手,用于添加从模型中字段的description属性中获取的标题(工具提示):

 public static MvcHtmlString TextBoxForWithTitle<Tmodel, TProperty>(this HtmlHelper<Tmodel> htmlHelper, Expression<Func<Tmodel, TProperty>> expression, object htmlAttributes = null)
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string textboxText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last();
        if (string.IsNullOrEmpty(textboxText))
            return MvcHtmlString.Empty;
        var textbox = new TagBuilder("input");
        textbox.MergeAttributes(new RouteValueDictionary(htmlAttributes));
        if (!string.IsNullOrEmpty(metaData.Description))
            textbox.Attributes.Add("title", metaData.Description);
        return MvcHtmlString.Create(textbox.ToString());
    }

我知道复选框也是一个'input'类型元素,但我不知道如何构造一个帮助器来将描述用作标题。

 public static MvcHtmlString CheckBoxForWithTitle<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string chkboxText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last();
        MemberExpression memberExpression = expression.Body as MemberExpression;
        string parameterName = memberExpression.Member.Name;

        if (string.IsNullOrEmpty(chkboxText))
            return MvcHtmlString.Empty;
        var chkbox = new MvcHtmlString(
            string.Format(
            "<input type=\"checkbox\" name=\"{0}\" id=\"{0}\" value=\"{1}\" {2} />",
            parameterName, 
        chkbox.MergeAttributes(new RouteValueDictionary(htmlAttributes));
        if (!string.IsNullOrEmpty(metaData.Description))
            chkbox.Attributes.Add("title", metaData.Description);
        return MvcHtmlString.Create(chkbox.ToString());
    }

2 个答案:

答案 0 :(得分:4)

您当前的实现没有考虑模型绑定和ModelState,不生成不显眼的验证所必需的属性,并且可能生成不正确的id属性。

在您自己的助手中使用现有的html助手方法,以便生成正确的html。您的TextBoxForWithTitle()方法只需

public static MvcHtmlString TextBoxForWithTitle<Tmodel, TProperty>(this HtmlHelper<Tmodel> htmlHelper, Expression<Func<Tmodel, TProperty>> expression, object htmlAttributes = null)
{
    var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    IDictionary<string, object> attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
    if (!string.IsNullOrEmpty(metaData.Description))
    {
        attributes.Add("title", metaData.Description);
    }
    return htmlHelper.TextBoxFor(expression, attributes);
}

并且类似地CheckBoxForWithTitle()将是相同的,除了

return htmlHelper.CheckBoxFor(expression, attributes);

旁注:要了解现有帮助程序的实际工作方式,您可以查看源代码here

答案 1 :(得分:0)

我尝试了它似乎到目前为止工作 - 仍然需要尝试一些我需要元素ID的例子:

 public static MvcHtmlString CheckBoxForWithTitle<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string chkboxText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last();
        MemberExpression memberExpression = expression.Body as MemberExpression;
        string parameterName = memberExpression.Member.Name;

        if (string.IsNullOrEmpty(chkboxText))
            return MvcHtmlString.Empty;
        var chkbox = new TagBuilder("input");
        chkbox.Attributes.Add("type", "checkbox");
        chkbox.MergeAttributes(new RouteValueDictionary(htmlAttributes));
        if (!string.IsNullOrEmpty(metaData.Description))
            chkbox.Attributes.Add("title", metaData.Description);
        return MvcHtmlString.Create(chkbox.ToString());
    }