你好,
我有一个带有[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 个月没有更新了。
如果由此造成任何不便,我们深表歉意。 我们要求如果您仍然遇到此问题,请用更新的信息记录一个新问题,我们将进行调查。
我在 Asp.Net Core 2.0 中也遇到了这种行为,引用的库包含一个面向 .Net Standard 2.0 的IValidatableObject
。
直到所有[Required]
验证都得到满足后,才会执行Validate()
中的自定义验证。 换句话说,在模型状态中报告任何其他内容之前,我必须将包含所有必填字段的对象发布到我的控制器。
modelstate
似乎首先关心 required ,然后是其他一切。 我还没有尝试过其他标准的验证属性,比如[StringLength()]
。
这真是令人讨厌的错误。 为什么要关闭?
很难构建事物并告诉人们数据注释有效,然后您会发现 IValidatableObject.Validate 如上所述运行。 这是一个问题,应该重新打开。
同时,我必须与认为这是好的编程的程序员打交道:
公共静态列表
{
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."));
}