借助其他一些StackOverflow问题,我编写了HTML Helper来获取属性的不干扰验证属性:
public static IHtmlString GetUnobtrusiveValidationAttributesFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> propertySelector)
{
string propertyName = html.NameFor(propertySelector).ToString();
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(propertySelector, html.ViewData);
//If the attributes were already generated, remove this flag so they can be generated again. Otherwise GetUnobtrusiveValidationAttributes returns empty
html.ViewContext.FormContext.RenderedField(propertyName, false);
var attributeCollection = html.GetUnobtrusiveValidationAttributes(metaData.PropertyName, metaData);
return html.Raw(String.Join(" ", attributeCollection.Select(kvp => kvp.Key + "=\"" + kvp.Value.ToString() + "\"")));
}
它似乎正常工作。请注意,为同一字段多次生成属性时,注释行显然是必需的。这是因为调用一次GetUnobtrusiveValidationAttributes
之后,会将完整的属性名称添加到HtmlHelper的私有ViewContext.FormContext._renderedFields
字典中,其值为true
。因此,我的注释行首先将其设置回false
,然后它将再次返回属性。
问题是在循环中,我的当前视图无法正常使用。我认为通过提供属性名称将最容易解释它。第一次调用propertyName
= "vm.CampPassPricePlans.CampPassPacks[0].SelectedCampPassExpirationRuleID"
。如您所见,该属性位于CampPassPacks
属性的第一项上,即List<t>
。下次通过propertyName
= "vm.CampPassPricePlans.CampPassPacks[1].SelectedCampPassExpirationRuleID"
,尽管GetUnobtrusiveValidationAttributes
将该属性的RenderedFields
设置为false
,但返回空结果。
我相信问题是,在我第一次调用GetUnobtrusiveValidationAttributes
之后,它在其内部_renderedFields
字典中添加了错误的属性名称。它没有添加"vm.CampPassPricePlans.CampPassPacks[0].SelectedCampPassExpirationRuleID"
,而只有"vm.CampPassPricePlans.SelectedCampPassExpirationRuleID"
。因此,它将它们全部内部转换为相同的名称。我怀疑这是因为html.ViewData.TemplateInfo.HtmlFieldPrefix
仅等于"vm.CampPassPricePlans"
-它不包含CampPassPacks
属性段或索引器。
I.E。 html.ViewData.TemplateInfo.HtmlFieldPrefix + "." + metaData.PropertyName
!= propertyName
。
为什么HtmlFieldPrefix
不包含完整前缀,什么是解决此问题的好方法?
编辑
我查看了GetUnobtrusiveValidationAttributes
源代码,这就是它的用途:
string fullName = html.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
其中name
是我传入的属性名称。
为什么这样做:
html.NameFor(propertySelector).ToString();
返回"vm.CampPassPricePlans.CampPassPacks[0].SelectedCampPassExpirationRuleID"
但是
html.ViewData.TemplateInfo.GetFullHtmlFieldName("SelectedCampPassExpirationRuleID")
返回"vm.CampPassPricePlans.SelectedCampPassExpirationRuleID"
吗?