Aspnetcore: IValidatableObject.Validate Hanya Dipanggil Jika Aturan Validasi yang Ditentukan Atribut Lulus?

Dibuat pada 11 Jan 2017  ·  3Komentar  ·  Sumber: dotnet/aspnetcore

Halo,

Saya memiliki objek dengan properti [Required] -decorated yang mengimplementasikan IValidatableObject . Selama pengikatan model, jika properti yang diperlukan adalah null, metode Validate() tidak pernah dipanggil. Apakah Validate() hanya dipanggil jika validasi yang dikonfigurasi atribut lolos?

Dalam kasus saya, jika pengguna mengirimkan formulir dengan kesalahan validasi, mereka pertama kali melihat pesan tentang bidang yang hilang. Kemudian, setelah kesalahan tersebut diselesaikan dan formulir dikirim ulang, daftar kesalahan tersebut disajikan dengan daftar kesalahan tambahan—kali ini, dibuat oleh Validate() . Apakah ada cara untuk memicu semua validasi terjadi pada saat yang sama sehingga pengguna disajikan dengan daftar _semua_ kesalahan yang memerlukan perhatian mereka ketika mereka pertama kali mengirimkan formulir?

Terima kasih,
Ben

Versi: ASP.Net Core 1.1.0/.Net 4.6.1

Contoh Kode

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

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

_Dari pengontrol:_

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

  // ...
}

Jika pengguna gagal mengisi bidang yang wajib diisi, mereka akan melihat pesan kesalahan tentangnya tetapi mereka tidak akan melihat pesan kesalahan lain yang mungkin ditambahkan oleh Validate().

Semua 3 komentar

Masalah ini sedang ditutup karena belum diperbarui dalam 3 bulan.

Kami mohon maaf jika hal ini menyebabkan ketidaknyamanan. Kami meminta jika Anda masih mengalami masalah ini, harap catat masalah baru dengan informasi terbaru dan kami akan menyelidikinya.

Saya mengalami perilaku ini juga di Asp.Net Core 2.0, dengan pustaka referensi yang berisi IValidatableObject penargetan .Net Standard 2.0.
Baru setelah semua validasi [Required] puas, validasi khusus di Validate() dijalankan. Dengan kata lain, saya harus memposting objek ke pengontrol saya dengan semua bidang yang diperlukan sebelum hal lain dilaporkan dalam modelstate.
modelstate tampaknya peduli tentang yang diperlukan terlebih dahulu, lalu yang lainnya. Saya belum mencoba atribut validasi standar lainnya seperti [StringLength()] .

Ini benar-benar bug yang mengganggu. Mengapa menutupnya?

Sulit untuk merancang hal-hal dan memberi tahu orang-orang bahwa anotasi data berfungsi maka Anda menemukan IValidatableObject.Validate berjalan seperti di atas. Ini adalah masalah dan ini HARUS dibuka kembali.

Sementara itu saya harus berurusan dengan programmer yang menganggap ini pemrograman yang bagus:
Daftar statis publikValidateUpdateDates (perintah ICommand)
{
var newErrors = Daftar baru();

        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."));
        }
Apakah halaman ini membantu?
0 / 5 - 0 peringkat