Aspnetcore: 仅当属性定义的验证规则通过时才调用 IValidatableObject.Validate?

创建于 2017-01-11  ·  3评论  ·  资料来源: dotnet/aspnetcore

你好,

我有一个带有[Required]装饰属性的对象,它实现了IValidatableObject 。 在模型绑定期间,如果所需属性为空,则永远不会调用对象的Validate()方法。 只有在属性配置的验证通过时才调用Validate()吗?

在我的例子中,如果用户提交一个带有验证错误的表单,他们首先会看到一条关于缺少字段的消息。 然后,一旦该错误得到解决并重新提交表单,他们就会看到一个额外的错误列表——这次是由Validate() 。 有没有办法同时触发所有验证,以便用户在第一次提交表单时看到需要他们注意的 _all_ 错误列表?

谢谢,

版本: ASP.Net Core 1.1.0/.Net 4.6.1

示例代码

public class Import : IValidatableObject
{
  [Required]
  public IFormFile File { get; set; }

  public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { /* ... */ }
  //...
}

_来自控制器:_

[HttpPost, ActionName("Index")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> IndexPost()
{
  var model = new ViewModels.Import();

  var bindingResult = await TryUpdateModelAsync(model, "", i => i.StartDate, i => i.EndDate, i => i.ImportTypeId, i => i.File);
  if (!bindingResult || ModelState.ValidationState != ModelValidationState.Valid) {
    return View(model);
  }

  // ...
}

如果用户未能填充必填字段,他们将看到有关它的错误消息,但他们不会看到 Validate() 可能添加的其他错误消息。

所有3条评论

这个问题正在关闭,因为它已经 3 个月没有更新了。

如果由此造成任何不便,我们深表歉意。 我们要求如果您仍然遇到此问题,请用更新的信息记录一个新问题,我们将进行调查。

我在 Asp.Net Core 2.0 中也遇到了这种行为,引用的库包含一个面向 .Net Standard 2.0 的IValidatableObject
直到所有[Required]验证都得到满足后,才会执行Validate()中的自定义验证。 换句话说,在模型状态中报告任何其他内容之前,我必须将包含所有必填字段的对象发布到我的控制器。
modelstate似乎首先关心 required ,然后是其他一切。 我还没有尝试过其他标准的验证属性,比如[StringLength()]

这真是令人讨厌的错误。 为什么要关闭?

很难构建事物并告诉人们数据注释有效,然后您会发现 IValidatableObject.Validate 如上所述运行。 这是一个问题,应该重新打开。

同时,我必须与认为这是好的编程的程序员打交道:
公共静态列表ValidateUpdateDates(ICommand 命令)
{
var newErrors = 新列表();

        var validator = new DataAnnotationsValidator();
        var results = new List<ValidationResult>();
        var isValid = validator.TryValidate(command, out results);

        if (!(command is UpdatePromotionCommand cpc))
            return newErrors;

        newErrors.AddRange(ValidateDatesAreValidFormat(cpc));

        if (
          !string.IsNullOrEmpty(cpc.PurchasePeriodStart)
          && !string.IsNullOrEmpty(cpc.PurchasePeriodEnd)
          && DateTime.TryParse(cpc.PurchasePeriodStart, out DateTime purchasePeriodStartDate)
          && DateTime.TryParse(cpc.PurchasePeriodEnd, out DateTime purchasePeriodEndDate)
          && purchasePeriodStartDate > purchasePeriodEndDate
        )
        {
            newErrors.Add(new ECError("Purchase Period End cannot be before Purchase Period Start."));
        }

        if (
          !string.IsNullOrEmpty(cpc.ClaimPeriodStart)
          && !string.IsNullOrEmpty(cpc.ClaimPeriodEnd)
          && DateTime.TryParse(cpc.ClaimPeriodStart, out DateTime claimPeriodStartDate)
          && DateTime.TryParse(cpc.ClaimPeriodEnd, out DateTime claimPeriodEndDate)
          && claimPeriodStartDate > claimPeriodEndDate
        )
        {
            newErrors.Add(new ECError("Claim Period End cannot be before Claim Period Start."));
        }
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

radenkozec picture radenkozec  ·  114评论

glennc picture glennc  ·  117评论

moodya picture moodya  ·  153评论

barrytang picture barrytang  ·  89评论

kevinchalet picture kevinchalet  ·  761评论