在使用Steven Sanderson的@Html.BeginCollectionItem帮助器时,我正在尝试使用IValidatableObject界面验证服务器端的集合项。
我想阻止用户选择两个相同的项目。因此,例如,给定用户说话的习语列表,可以回发这些值:
English
English
Spanish
Validate
实现如下所示:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
foreach(var idiom in Idioms)
{
if(Idioms.Any(i => i != idiom && i.Idiom == idiom.Idiom))
{
yield return new ValidationResult("Idiom already selected", new string[] { "Idiom" });
}
}
}
问题在于,传递给MemberName
的{{1}}(“Idiom”)与ValidationResult
字典中存在的MemberName
不同,因为帮助者是史蒂文使用ModelState
,看起来像这样:
Guid
你可以看到[42] = {[Idioms[83c2c6db-0157-42f3-bf3f-f7c9e6bc0a37].Idiom, System.Web.Mvc.ModelState]}
。
在最好的情况下,我必须有一种传递方式,例如Idiom != [Idioms[83c2c6db-0157-42f3-bf3f-f7c9e6bc0a37].Idiom
作为[Idioms[83c2c6db-0157-42f3-bf3f-f7c9e6bc0a37].Idiom
,但我不知道如何从MemberName
获取此信息或即使这是可能的。无论如何,这必须是动态的。
你知道如何克服这个问题吗?
答案 0 :(得分:0)
经过大量的谷歌搜索后,我找到了正确的方法来做我想要的事情:
Model Validation in ASP.NET MVC 3
要在ViewModel
的集合/列表属性中验证(即找到重复的条目),您必须添加
@Html.ValidationMessageFor(u => u.Idioms)
表示View
中的媒体资源,并在errorMessage
方法中撰写Validate
。最后将消息分配给正确的属性名称,即在我的情况下为Idioms
。
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var grouping = Idioms.GroupBy(ui => ui.Idiom);
var duplicates = grouping.Where(group => group.Count() > 1);
if(duplicates.Any())
{
string message = string.Empty;
foreach(var duplicate in duplicates)
{
message += string.Format("{0} was selected {1} times", duplicate.Key, duplicate.Count());
}
yield return new ValidationResult(message, new[] { "Idioms" });
}
}
<强>奖金强>
如果您想在separate lines
中显示每个重复的组(添加换行符<br>
),请执行以下操作:
将{0} was selected {1} times
替换为{0} was selected {1} times<br>
然后在View
方面执行此操作:
@Html.Raw(HttpUtility.HtmlDecode(Html.ValidationMessageFor(u => u.Idioms).ToHtmlString()))
输出将是:
French was selected 2 times
English was selected 3 times