【问题标题】:ValidationSummary displays duplicate messagesValidationSummary 显示重复消息
【发布时间】:2011-12-07 16:20:28
【问题描述】:

如果两个文本框同时验证失败,则 ValidationSummary 会显示相同的消息两次。

我做错了吗?或者有没有我可以更改的设置来隐藏重复的消息?

 

我已经把它分解成最简单的例子:

查看:

@model MyModel
@Html.ValidationSummary()
@Html.TextBoxFor(model => model.A)
@Html.TextBoxFor(model => model.B)

型号:

public class MyModel : IValidatableObject
{
    public int A { get; set; }
    public int B { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        //Some logic goes here.        
        yield return new ValidationResult("Validation failed", new[] { "A", "B" });
    }
}

结果:

【问题讨论】:

    标签: asp.net-mvc validationsummary


    【解决方案1】:

    从 ValidationSummary 的角度来看,它们不是重复的 - 您将模型状态错误分配给字段 A 和 B,因此验证摘要中必须有 2 个错误。它不“知道”它们是相同的。

    简单的解决方案:

    • 仅将模型分配给其中之一
    • 从摘要中排除属性分配的错误 - Html.ValidationSummary(true)

    有点困难的解决方案:

    • 制作您自己的 ValidationSummary 助手,在其中调用标准验证摘要逻辑,然后以“选择不同”的方式过滤结果(linq 是您的朋友)。

    编辑:

    例如这样的:

    public static class ValidationExtensions
    {
        public static MvcHtmlString FilteredValidationSummary(this HtmlHelper html)
        {
            // do some filtering on html.ViewData.ModelState 
            return System.Web.Mvc.Html.ValidationExtensions.ValidationSummary(html);
        }
    }
    

    【讨论】:

    • 谢谢,我已经成功创建了我的自定义助手,它现在运行良好。唯一的问题是它大部分是硬编码的。您提到了“标准验证摘要逻辑”。你有什么特别的想法还是只是一个一般性的陈述?
    【解决方案2】:

    这是你的观点

    <ul class="validation-summary-errors">
        @{
            string errorMessage = "", previousError = "";
            foreach (ModelState modelState in (ViewContext.ViewData.ModelState.Values)){
    
                foreach (ModelError modelError in modelState.Errors)
                {
                    errorMessage = modelError.ErrorMessage;
                    if (errorMessage != previousError)
                    {
                        <li>@modelError.ErrorMessage</li>
                        previousError = modelError.ErrorMessage;
                    }                            
                }    
            }
        }
    </ul>
    

    您也许可以改进这一点,因为它仅在 2 个连续错误相同时才有效,如果顺序混乱,这可能不起作用,但这会让您开始。我想您可以构建一个错误消息数组并在每次运行时检查错误,但这个解决方案似乎大部分时间都有效。

    【讨论】:

    • 如果您使用 List 错误,这个特定的解决方案效果会更好。当您遍历错误时,使用 list.Contains() 检查您是否已经处理了错误。如果还没有,请将其放入列表中,然后用
    • 标记显示它。 T
    【解决方案3】:

    ValidationSummary 方法返回属性级和模型级错误。如果您不指定任何参数,它只会枚举所有验证消息。

    您可以: 1) 对字段 A 和 B 使用不同的消息

    // logic here
    yield return new ValidationResult("Validation failed for left field", new[] { "A" });
    // logic here
    yield return new ValidationResult("Validation failed for right field", new[] { "B" });
    

    或者,在你看来

    2) 调用 ValidationSummary 并将 excludePropertyErrors 参数设置为 true - ValidationSummary(true)。并在您的每个领域附近拨打Html.ValidationMessage[For]

    UPDT: ...和第三种情况:

    在您的模型中添加通用消息(模型级):

    //logic here
    yield return new ValidationResult("Validation failed");
    yield return new ValidationResult("any text or empty string", new[] { "A", "B" });
    

    在您看来,排除属性消息,但不要为字段添加 ValidationMessage:

    @model MyModel
    @Html.ValidationSummary(true)
    @Html.TextBoxFor(model => model.A)
    @Html.TextBoxFor(model => model.B)
    

    所以你会得到一条消息和两个红色框。

    【讨论】:

    • 谢谢。当只有一对字段导致我出现问题时,排除所有属性错误接缝有点极端。我不明白他们为什么要建立一种方法来验证具有如此明显问题的多个字段。
    • 我同意在像你这样的情况下不太方便。但是典型的使用验证助手是ValidationSummary(true) 和'ValidationFor',比如@model MyModel @Html.ValidationSummary(true) @Html.TextBoxFor(model =&gt; model.A) @Html.ValidationFor(model =&gt; model.A) @Html.TextBoxFor(model =&gt; model.B) @Html.ValidationFor(model =&gt; model.B)
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签