Bagikan melalui


Memvalidasi dengan Antarmuka IDataErrorInfo (C#)

oleh Stephen Walther

Stephen Walther menunjukkan kepada Anda cara menampilkan pesan kesalahan validasi kustom dengan menerapkan antarmuka IDataErrorInfo di kelas model.

Tujuan dari tutorial ini adalah untuk menjelaskan salah satu pendekatan untuk melakukan validasi dalam aplikasi MVC ASP.NET. Anda mempelajari cara mencegah seseorang mengirimkan formulir HTML tanpa menyediakan nilai untuk bidang formulir yang diperlukan. Dalam tutorial ini, Anda mempelajari cara melakukan validasi dengan menggunakan antarmuka IErrorDataInfo.

Asumsi

Dalam tutorial ini, saya akan menggunakan database MoviesDB dan tabel database Film. Tabel ini memiliki kolom berikut:

Nama Kolom Jenis Data Perbolehkan Null
Id Int FALSE
Judul Nvarchar(100) Salah
direktur Nvarchar(100) FALSE
DateReleased DateTime Salah

Dalam tutorial ini, saya menggunakan Microsoft Entity Framework untuk menghasilkan kelas model database saya. Kelas Film yang dihasilkan oleh Kerangka Kerja Entitas ditampilkan dalam Gambar 1.

Entitas Film

Gambar 01: Entitas Film (Klik untuk melihat gambar ukuran penuh)

Catatan

Untuk mempelajari selengkapnya tentang menggunakan Kerangka Kerja Entitas untuk menghasilkan kelas model database Anda, lihat tutorial saya yang berjudul Membuat Kelas Model dengan Kerangka Kerja Entitas.

Kelas Pengontrol

Kami menggunakan pengontrol Rumah untuk mencantumkan film dan membuat film baru. Kode untuk kelas ini terkandung dalam Daftar 1.

Daftar 1 - Controllers\HomeController.cs

using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{

    public class HomeController : Controller
    {
        private MoviesDBEntities _db = new MoviesDBEntities();

        public ActionResult Index()
        {
            return View(_db.MovieSet.ToList());
        }

        public ActionResult Create()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude = "Id")] Movie movieToCreate)
        {
            // Validate
            if (!ModelState.IsValid)
                return View();

            // Add to database
            try
            {
                _db.AddToMovieSet(movieToCreate);
                _db.SaveChanges();

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

    }
}

Kelas Pengontrol Beranda di Listing 1 berisi dua tindakan Create(). Tindakan pertama menampilkan formulir HTML untuk membuat film baru. Tindakan Buat() kedua melakukan penyisipan aktual film baru ke dalam database. Tindakan Create() kedua dipanggil ketika formulir yang ditampilkan oleh tindakan Create() pertama dikirimkan ke server.

Perhatikan bahwa tindakan Create() kedua berisi baris kode berikut:

// Validate
if (!ModelState.IsValid)
    return View();

Properti IsValid mengembalikan false ketika ada kesalahan validasi. Dalam hal ini, tampilan Buat yang berisi formulir HTML untuk membuat film diputar ulang.

Membuat Kelas Parsial

Kelas Film dihasilkan oleh Kerangka Kerja Entitas. Anda dapat melihat kode untuk kelas Film jika Anda memperluas file MoviesDBModel.edmx di jendela Penjelajah Solusi dan membuka MoviesDBModel. Designer.cs di Editor Kode (lihat Gambar 2).

Kode untuk entitas Film

Gambar 02: Kode untuk entitas Film (Klik untuk melihat gambar ukuran penuh)

Kelas Film adalah kelas parsial. Itu berarti bahwa kita dapat menambahkan kelas parsial lain dengan nama yang sama untuk memperluas fungsionalitas kelas Film. Kami akan menambahkan logika validasi kami ke kelas parsial baru.

Tambahkan kelas di Daftar 2 ke folder Model.

Daftar 2 - Models\Movie.cs

using System.Collections.Generic;
using System.ComponentModel;

namespace MvcApplication1.Models
{

    public partial class Movie 
    {

    }
}

Perhatikan bahwa kelas di Listing 2 menyertakan pengubah parsial . Metode atau properti apa pun yang Anda tambahkan ke kelas ini menjadi bagian dari kelas Film yang dihasilkan oleh Kerangka Kerja Entitas.

Menambahkan Metode Parsial OnChanging dan OnChanged

Saat Kerangka Kerja Entitas menghasilkan kelas entitas, Kerangka Kerja Entitas menambahkan metode parsial ke kelas secara otomatis. Entity Framework menghasilkan metode parsial OnChanging dan OnChanged yang sesuai dengan setiap properti kelas.

Dalam kasus kelas Film, Kerangka Kerja Entitas membuat metode berikut:

  • OnIdChanging
  • OnIdChanged
  • OnTitleChanging
  • OnTitleChanged
  • OnDirectorChanging
  • OnDirectorChanged
  • OnDateReleasedChanging
  • OnDateReleasedChanged

Metode OnChanging dipanggil tepat sebelum properti yang sesuai diubah. Metode OnChanged dipanggil tepat setelah properti diubah.

Anda dapat memanfaatkan metode parsial ini untuk menambahkan logika validasi ke kelas Film. Kelas perbarui Film di Daftar 3 memverifikasi bahwa properti Judul dan Direktur diberi nilai kosong.

Catatan

Metode parsial adalah metode yang ditentukan dalam kelas yang tidak perlu Anda terapkan. Jika Anda tidak menerapkan metode parsial, pengkompilasi akan menghapus tanda tangan metode dan semua panggilan ke metode sehingga tidak ada biaya run-time yang terkait dengan metode parsial. Di Editor Visual Studio Code, Anda dapat menambahkan metode parsial dengan mengetikkan sebagian kata kunci diikuti dengan spasi untuk melihat daftar parsial yang akan diterapkan.

Daftar 3 - Models\Movie.cs

using System.Collections.Generic;
using System.ComponentModel;

namespace MvcApplication1.Models
{

    public partial class Movie : IDataErrorInfo
    {
        private Dictionary<string, string> _errors = new Dictionary<string, string>();

        partial void OnTitleChanging(string value)
        {
            if (value.Trim().Length == 0)
                _errors.Add("Title", "Title is required.");
        }

        partial void OnDirectorChanging(string value)
        {
            if (value.Trim().Length == 0)
                _errors.Add("Director", "Director is required.");
        }

    }
}

Misalnya, jika Anda mencoba menetapkan string kosong ke properti Judul, maka pesan kesalahan ditetapkan ke Kamus bernama _errors.

Pada titik ini, tidak ada yang benar-benar terjadi ketika Anda menetapkan string kosong ke properti Judul dan kesalahan ditambahkan ke bidang _errors privat. Kita perlu mengimplementasikan antarmuka IDataErrorInfo untuk mengekspos kesalahan validasi ini ke kerangka kerja MVC ASP.NET.

Menerapkan Antarmuka IDataErrorInfo

Antarmuka IDataErrorInfo telah menjadi bagian dari kerangka kerja .NET sejak versi pertama. Antarmuka ini adalah antarmuka yang sangat sederhana:

public interface IDataErrorInfo
{
    string this[string columnName] { get; }

    string Error { get; }
}

Jika kelas mengimplementasikan antarmuka IDataErrorInfo, kerangka kerja MVC ASP.NET akan menggunakan antarmuka ini saat membuat instans kelas. Misalnya, tindakan Buat() pengontrol Beranda menerima instans kelas Film:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "Id")] Movie movieToCreate)
{
    // Validate
    if (!ModelState.IsValid)
        return View();

    // Add to database
    try
    {
        _db.AddToMovieSet(movieToCreate);
        _db.SaveChanges();

        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
}

Kerangka kerja MVC ASP.NET membuat instans Film yang diteruskan ke tindakan Create() dengan menggunakan pengikat model (DefaultModelBinder). Pengikat model bertanggung jawab untuk membuat instans objek Film dengan mengikat bidang formulir HTML ke instans objek Film.

DefaultModelBinder mendeteksi apakah kelas mengimplementasikan antarmuka IDataErrorInfo atau tidak. Jika kelas mengimplementasikan antarmuka ini, maka pengikat model memanggil IDataErrorInfo.pengindeks ini untuk setiap properti kelas. Jika pengindeks mengembalikan pesan kesalahan, pengikat model menambahkan pesan kesalahan ini ke status model secara otomatis.

DefaultModelBinder juga memeriksa properti IDataErrorInfo.Error. Properti ini dimaksudkan untuk mewakili kesalahan validasi spesifik non-properti yang terkait dengan kelas . Misalnya, Anda mungkin ingin menerapkan aturan validasi yang bergantung pada nilai beberapa properti kelas Film. Dalam hal ini, Anda akan mengembalikan kesalahan validasi dari properti Kesalahan.

Kelas Film yang diperbarui di Listing 4 mengimplementasikan antarmuka IDataErrorInfo.

Daftar 4 - Models\Movie.cs (mengimplementasikan IDataErrorInfo)

using System.Collections.Generic;
using System.ComponentModel;

namespace MvcApplication1.Models
{

    public partial class Movie : IDataErrorInfo
    {
        private Dictionary<string, string> _errors = new Dictionary<string, string>();

        partial void OnTitleChanging(string value)
        {
            if (value.Trim().Length == 0)
                _errors.Add("Title", "Title is required.");
        }

        partial void OnDirectorChanging(string value)
        {
            if (value.Trim().Length == 0)
                _errors.Add("Director", "Director is required.");
        }

        #region IDataErrorInfo Members

        public string Error
        {
            get
            {
                return string.Empty;
            }
        }

        public string this[string columnName]
        {
            get
            {
                if (_errors.ContainsKey(columnName))
                    return _errors[columnName];
                return string.Empty;
            }
        }

        #endregion
    }
}

Di Daftar 4, properti pengindeks memeriksa koleksi _errors untuk melihat apakah berisi kunci yang sesuai dengan nama properti yang diteruskan ke pengindeks. Jika tidak ada kesalahan validasi yang terkait dengan properti, string kosong akan dikembalikan.

Anda tidak perlu memodifikasi pengontrol Beranda dengan cara apa pun untuk menggunakan kelas Film yang dimodifikasi. Halaman yang ditampilkan di Gambar 3 menggambarkan apa yang terjadi ketika tidak ada nilai yang dimasukkan untuk bidang formulir Judul atau Direktur.

Membuat metode tindakan secara otomatis

Gambar 03: Formulir dengan nilai yang hilang (Klik untuk melihat gambar ukuran penuh)

Perhatikan bahwa nilai DateReleased divalidasi secara otomatis. Karena properti DateReleased tidak menerima nilai NULL, DefaultModelBinder menghasilkan kesalahan validasi untuk properti ini secara otomatis ketika tidak memiliki nilai. Jika Anda ingin mengubah pesan kesalahan untuk properti DateReleased maka Anda perlu membuat pengikat model kustom.

Ringkasan

Dalam tutorial ini, Anda mempelajari cara menggunakan antarmuka IDataErrorInfo untuk menghasilkan pesan kesalahan validasi. Pertama, kami membuat kelas Film parsial yang memperluas fungsionalitas kelas Film parsial yang dihasilkan oleh Kerangka Kerja Entitas. Selanjutnya, kami menambahkan logika validasi ke kelas Film OnTitleChanging() dan metode parsial OnDirectorChanging(). Terakhir, kami menerapkan antarmuka IDataErrorInfo untuk mengekspos pesan validasi ini ke kerangka kerja MVC ASP.NET.