Можете ли вы уточнить, какие проблемы у вас есть?
Например, есть элегантный подход к editing variable length list с validation support. Хотя он не использует шаблоны, все еще остается СУХОЙ с частичными видами.
В то время как идентификаторы несовместимы - имена в порядке и только проблема, с которой я столкнулся, заключается в том, что с использованием jquery.infieldlabel оказалось, что атрибут label для атрибута (сгенерированного GetFullHtmlFieldId внутри помощника LabelFor) не соответствует идентификатору соответствующего ввода TextBoxFor. Таким образом, я создал метод помощника LabelForCollectionItem, который просто использует тот же метод для генерации id, что и TextBox. TagBuilder.GenerateId(fullName)
Возможно, код не соответствует вашим потребностям, но надеюсь, что это поможет кому-то, так как я нашел ваш вопрос среди первого поиска решение моей проблемы.
public static class LabelExtensions
{
/// <summary>
/// Generates Label with "for" attribute corresponding to the id rendered by input (e.g. TextBoxFor),
/// for the case when input is a collection item (full name contains []).
/// GetFullHtmlFieldId works incorrect inside Html.BeginCollectionItem due to brackets presense.
/// This method copies TextBox's id generation.
/// </summary>
public static MvcHtmlString LabelForCollectionItem<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression,
string labelText = null, object htmlAttributes = null) where TModel : class
{
var tag = new TagBuilder("label");
tag.MergeAttributes(new RouteValueDictionary(htmlAttributes)); // to convert an object into an IDictionary
// set inner text
string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
string innerText = labelText ?? GetDefaultLabelText(html, expression, htmlFieldName);
if (string.IsNullOrEmpty(innerText))
{
return MvcHtmlString.Empty;
}
tag.SetInnerText(innerText);
// set for attribute
string forId = GenerateTextBoxId(tag, html, htmlFieldName);
tag.Attributes.Add("for", forId);
return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}
/// <summary>
/// Extracted from System.Web.Mvc.Html.InputExtensions
/// </summary>
private static string GenerateTextBoxId<TModel>(TagBuilder tagBuilder, HtmlHelper<TModel> html, string htmlFieldName)
{
string fullName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName);
tagBuilder.GenerateId(fullName);
string forId = tagBuilder.Attributes["id"];
tagBuilder.Attributes.Remove("id");
return forId;
}
/// <summary>
/// Extracted from System.Web.Mvc.Html.LabelExtensions
/// </summary>
private static string GetDefaultLabelText<TModel, TValue>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, string htmlFieldName)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
return labelText;
}
}
Итак, в вашем методе, что произойдет, если htmlFieldName содержит квадратные скобки? например «Пользователи [0]» –
Html.LabelForCollectionItem (x => x.Users [0] .Name) возвращает
Это интересный способ сделать это, помог мне подняться с решением для нашей конкретной ситуации. Благодаря! (Я бы проголосовал за ваш ответ, если вы можете отредактировать его - так что обойдусь глупыми правилами stackoverflow) –