代码之家  ›  专栏  ›  技术社区  ›  Leniel Maccaferri

@具有IValidatableObject和MemberName的Html.BeginCollectionItem不匹配

  •  0
  • Leniel Maccaferri  · 技术社区  · 11 年前

    使用时 @Html.BeginCollectionItem Steven Sanderson的助手我正在尝试验证 集合项目 在服务器端使用 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 (“白痴”)传递给 ValidationResult 成员名称 出现在 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 作为 成员名称 但我不知道如何从 validationContext 或者即使这是可能的。无论如何,这必须是动态的。

    你知道克服这个问题的方法吗?

    1 回复  |  直到 11 年前
        1
  •  0
  •   Leniel Maccaferri    11 年前

    在谷歌上搜索了很多之后,我找到了做我想做的事情的正确方法:

    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>

    然后在 看法 侧面进行此操作:

    @Html.Raw(HttpUtility.HtmlDecode(Html.ValidationMessageFor(u => u.Idioms).ToHtmlString()))
    

    输出将为:

    French was selected 2 times
    English was selected 3 times