こんにちは、
IValidatableObject
を実装する[Required]
装飾されたプロパティを持つオブジェクトがあります。 モデルのバインド中に、必要なプロパティがnullの場合、オブジェクトのValidate()
メソッドが呼び出されることはありません。 Validate()
は、属性構成の検証に合格した場合にのみ呼び出されますか?
私の場合、ユーザーが検証エラーのあるフォームを送信すると、最初に不足しているフィールドに関するメッセージが表示されます。 次に、そのエラーが解決され、フォームが再送信されると、エラーの追加リストが表示されます。今回は、 Validate()
によって生成されます。 すべての検証を同時に実行して、ユーザーが最初にフォームを送信するときに注意が必要なすべてのエラーのリストが表示されるようにする方法はありますか?
ありがとう、
ベン
バージョン: 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 Standard2.0を対象とするIValidatableObject
を含む参照ライブラリがあります。
Validate()
のカスタム検証が実行されるのは、すべての[Required]
検証が満たされるまでです。 つまり、modelstateで他の何かが報告される前に、すべての必須フィールドを含むオブジェクトをコントローラーに投稿する必要があります。
modelstate
は、最初に必要なものを気にし、次に他のすべてを気にするようです。 [StringLength()]
ような他の標準検証属性は試していません。
これは本当に厄介なバグです。 なぜそれを閉じるのですか?
物事を設計して人々にデータ注釈が機能することを伝えるのは難しいので、IValidatableObject.Validateは上記のように実行されます。 これは問題であり、これを再開する必要があります。
その間、私はこれが良いプログラミングだと思うプログラマーに対処しなければなりません:
パブリック静的リスト
{{
var newErrors = new List
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."));
}