Создать checkboxFor помощник MVC с атрибутом title из описания модели

Я создал помощник текстового поля для добавления заголовка (всплывающей подсказки), взятого из атрибута описания для поля в модели:

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());
 }
</func<tmodel,></tmodel></tmodel,>

Я знаю, что флажок также является элементом типа ввода, но я понятия не имею, как создать помощника, чтобы использовать описание в качестве заголовка.

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(
 "",
 parameterName, 
 chkbox.MergeAttributes(new RouteValueDictionary(htmlAttributes));
 if (!string.IsNullOrEmpty(metaData.Description))
 chkbox.Attributes.Add("title", metaData.Description);
 return MvcHtmlString.Create(chkbox.ToString());
 }
</func<tmodel,></tmodel></tmodel,>
2 ответа

В текущих реализациях не учитывается привязка модели и 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);
}
</string,></func<tmodel,></tmodel></tmodel,>

и аналогичным образом CheckBoxForWithTitle() будет таким же, кроме

return htmlHelper.CheckBoxFor(expression, attributes);

Боковое примечание. Чтобы узнать, как работают настоящие помощники, вы можете просмотреть исходный код здесь


Я пробовал и, похоже, работает до сих пор - все равно придется попробовать несколько примеров, где мне нужен идентификатор элемента:

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());
 }
</func<tmodel,></tmodel></tmodel,>

licensed under cc by-sa 3.0 with attribution.