ValidationSummary 显示重复消息

发布于 2024-12-09 13:49:03 字数 749 浏览 0 评论 0原文

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

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

 

我将其分解为最简单的示例:

View:

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

Model:

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" });
    }
}

Result:

在此处输入图像描述

If two of textboxes fail validation at once then the ValidationSummary displays the same message twice.

Am I doing something wrong? Or is there a setting I can change to hide duplicate messages?

 

I have broken it down to the simplest example:

View:

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

Model:

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" });
    }
}

Result:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深海里的那抹蓝 2024-12-16 13:49:03

从 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);
    }
}

They are not duplicate from the point of view of ValidationSummary - you are assigning model state error to both fields A and B, so there must be 2 errors in validation summary. It doesnt "know" that they are the same.

Easy solutions :

  • assign model only to one of them
  • exclude property-assigned errors from summary - Html.ValidationSummary(true)

A little bit harder solution :

  • make your own ValidationSummary helper, call standard validation summary logic in it, and then filter the result in "select distinct" way (linq is your friend here).

EDIT:

something like this for example :

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);
    }
}
寄居者 2024-12-16 13:49:03

这是你的视图,

<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>

你也许可以改进它,因为它只有在两个连续错误相同时才有效,如果它打乱了顺序,这可能不起作用,但这会让你开始。我想您可以构建一组错误消息并在每次运行时检查错误,但此解决方案似乎在大多数情况下都有效。

Whack this is your View

<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>

You might be able to improve this as it only works when 2 consecutive errors are the same, if it jumbles the order this might not work, but this will start you off. I suppose you could build an array of error messages and check the error off it each run through, but this solution seems to work most of the time.

痴情换悲伤 2024-12-16 13:49:03

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,并将 exceptPropertyErrors 参数设置为 true - ValidationSummary(true)。并将调用 Html.ValidationMessage[For] 放在每个字段附近。

更新:
...第三种情况:

在您的模型中添加公共消息(模型级别):

//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 method returns property-level and model-level errors. It just enumerates all validation messages if you don't specify any arguments.

You can:
1) Use different message for field A and 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" });

or, in your view

2) Call ValidationSummary with excludePropertyErrors argument set to true - ValidationSummary(true). And place call Html.ValidationMessage[For] near each of your fields.

UPDT:
... and third case:

In your model add common message (model-level):

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

In your view exclude property messages but don't add ValidationMessage for fields:

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

So you'll get single message and both red boxes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文