Bagikan melalui


Iterasi #3 – Tambahkan validasi formulir (VB)

oleh Microsoft

Unduh Kode

Dalam iterasi ketiga, kami menambahkan validasi formulir dasar. Kami mencegah orang mengirimkan formulir tanpa melengkapi bidang formulir yang diperlukan. Kami juga memvalidasi alamat email dan nomor telepon.

Membangun Manajemen Kontak ASP.NET Aplikasi MVC (VB)

Dalam rangkaian tutorial ini, kami membangun seluruh aplikasi Manajemen Kontak dari awal hingga akhir. Aplikasi Contact Manager memungkinkan Anda menyimpan informasi kontak - nama, nomor telepon, dan alamat email - untuk daftar orang.

Kami membangun aplikasi melalui beberapa iterasi. Dengan setiap iterasi, kami secara bertahap meningkatkan aplikasi. Tujuan dari pendekatan perulangan ganda ini adalah untuk memungkinkan Anda memahami alasan setiap perubahan.

  • Iterasi #1 - Buat aplikasi. Dalam iterasi pertama, kami membuat Contact Manager dengan cara yang paling sederhana. Kami menambahkan dukungan untuk operasi database dasar: Buat, Baca, Perbarui, dan Hapus (CRUD).

  • Iterasi #2 - Membuat aplikasi terlihat bagus. Dalam perulangan ini, kami meningkatkan tampilan aplikasi dengan memodifikasi halaman master tampilan ASP.NET MVC default dan lembar gaya bertingkat.

  • Iterasi #3 - Tambahkan validasi formulir. Dalam iterasi ketiga, kami menambahkan validasi formulir dasar. Kami mencegah orang mengirimkan formulir tanpa melengkapi bidang formulir yang diperlukan. Kami juga memvalidasi alamat email dan nomor telepon.

  • Iterasi #4 - Buat aplikasi digabungkan secara longgar. Dalam iterasi keempat ini, kami memanfaatkan beberapa pola desain perangkat lunak untuk mempermudah pemeliharaan dan modifikasi aplikasi Contact Manager. Misalnya, kami merefaktor aplikasi kami untuk menggunakan pola Repositori dan pola Injeksi Dependensi.

  • Iterasi #5 - Membuat pengujian unit. Dalam iterasi kelima, kami membuat aplikasi kami lebih mudah dirawat dan dimodifikasi dengan menambahkan pengujian unit. Kami meniru kelas model data kami dan membangun pengujian unit untuk pengontrol dan logika validasi kami.

  • Iterasi #6 - Gunakan pengembangan berbasis pengujian. Dalam iterasi keenam ini, kami menambahkan fungsionalitas baru ke aplikasi kami dengan menulis pengujian unit terlebih dahulu dan menulis kode terhadap pengujian unit. Dalam perulangan ini, kami menambahkan grup kontak.

  • Iterasi #7 - Tambahkan fungsionalitas Ajax. Dalam iterasi ketujuh, kami meningkatkan responsivitas dan performa aplikasi kami dengan menambahkan dukungan untuk Ajax.

Perulangan Ini

Dalam iterasi kedua aplikasi Contact Manager ini, kami menambahkan validasi formulir dasar. Kami mencegah orang mengirimkan kontak tanpa memasukkan nilai untuk bidang formulir yang diperlukan. Kami juga memvalidasi nomor telepon dan alamat email (lihat Gambar 1).

Kotak dialog Proyek Baru

Gambar 01: Formulir dengan validasi (Klik untuk melihat gambar ukuran penuh)

Dalam perulangan ini, kami menambahkan logika validasi langsung ke tindakan pengontrol. Secara umum, ini bukan cara yang disarankan untuk menambahkan validasi ke aplikasi MVC ASP.NET. Pendekatan yang lebih baik adalah menempatkan logika validasi aplikasi di lapisan layanan terpisah. Dalam iterasi berikutnya, kami merefaktor aplikasi Contact Manager untuk membuat aplikasi lebih dapat dipertahankan.

Dalam iterasi ini, untuk menjaga semuanya tetap sederhana, kita menulis semua kode validasi dengan tangan. Alih-alih menulis kode validasi sendiri, kita bisa memanfaatkan kerangka kerja validasi. Misalnya, Anda dapat menggunakan Blok Aplikasi Validasi Pustaka Perusahaan Microsoft (VAB) untuk menerapkan logika validasi untuk aplikasi MVC ASP.NET Anda. Untuk mempelajari selengkapnya tentang Blok Aplikasi Validasi, lihat:

http://msdn.microsoft.com/library/dd203099.aspx

Menambahkan Validasi ke Tampilan Buat

Mari kita mulai dengan menambahkan logika validasi ke tampilan Buat. Untungnya, karena kami membuat tampilan Buat dengan Visual Studio, tampilan Buat sudah berisi semua logika antarmuka pengguna yang diperlukan untuk menampilkan pesan validasi. Tampilan Buat terkandung dalam Daftar 1.

Daftar 1 - \Views\Contact\Create.aspx

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of ContactManager.Contact)" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Create</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <%= Html.ValidationSummary() %>

    <% Using Html.BeginForm()%>

        <fieldset>
            <legend>Create New Contact</legend>
            <p>
                <label for="FirstName">First Name:</label>
                <%= Html.TextBox("FirstName") %>
                <%= Html.ValidationMessage("FirstName", "*") %>
            </p>
            <p>
                <label for="LastName">Last Name:</label>
                <%= Html.TextBox("LastName") %>
                <%= Html.ValidationMessage("LastName", "*") %>
            </p>
            <p>
                <label for="Phone">Phone:</label>
                <%= Html.TextBox("Phone") %>
                <%= Html.ValidationMessage("Phone", "*") %>
            </p>
            <p>
                <label for="Email">Email:</label>
                <%= Html.TextBox("Email") %>
                <%= Html.ValidationMessage("Email", "*") %>
            </p>
            <p class="submit">
                <input type="submit" value="Create" />
            </p>
        </fieldset>

    <% End Using %>

</asp:Content>

Kelas field-validation-error digunakan untuk menata output yang dirender oleh pembantu Html.ValidationMessage(). Kelas input-validation-error digunakan untuk menata kotak teks (input) yang dirender oleh pembantu Html.TextBox(). Kelas validation-summary-errors digunakan untuk menata daftar yang tidak diurutkan yang dirender oleh pembantu Html.ValidationSummary().

Catatan

Anda dapat mengubah kelas lembar gaya yang dijelaskan di bagian ini untuk menyesuaikan tampilan pesan kesalahan validasi.

Menambahkan Logika Validasi ke Buat Tindakan

Saat ini, tampilan Buat tidak pernah menampilkan pesan kesalahan validasi karena kami belum menulis logika untuk menghasilkan pesan apa pun. Untuk menampilkan pesan kesalahan validasi, Anda perlu menambahkan pesan kesalahan ke ModelState.

Catatan

Metode UpdateModel() menambahkan pesan kesalahan ke ModelState secara otomatis ketika ada kesalahan yang menetapkan nilai bidang formulir ke properti. Misalnya, jika Anda mencoba menetapkan string "apple" ke properti BirthDate yang menerima nilai DateTime, metode UpdateModel() menambahkan kesalahan ke ModelState.

Metode Create() yang dimodifikasi di Listing 2 berisi bagian baru yang memvalidasi properti kelas Kontak sebelum kontak baru dimasukkan ke dalam database.

Daftar 2 - Controllers\ContactController.vb (Buat dengan validasi)

<AcceptVerbs(HttpVerbs.Post)> _
Function Create(<Bind(Exclude:="Id")> ByVal contactToCreate As Contact) As ActionResult
    ' Validation logic
    If contactToCreate.FirstName.Trim().Length = 0 Then
        ModelState.AddModelError("FirstName", "First name is required.")
    End If
    If contactToCreate.LastName.Trim().Length = 0 Then
        ModelState.AddModelError("LastName", "Last name is required.")
    End If
    If (contactToCreate.Phone.Length > 0 AndAlso Not Regex.IsMatch(contactToCreate.Phone, "((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))
        ModelState.AddModelError("Phone", "Invalid phone number.")
    End If        
    If (contactToCreate.Email.Length > 0 AndAlso  Not Regex.IsMatch(contactToCreate.Email, "^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
        ModelState.AddModelError("Email", "Invalid email address.")
    End If
    If Not ModelState.IsValid Then
        Return View()
    End If

    ' Database logic
    Try
        _entities.AddToContactSet(contactToCreate)
        _entities.SaveChanges()
        Return RedirectToAction("Index")
    Catch
        Return View()
    End Try
End Function

Bagian validasi memberlakukan empat aturan validasi yang berbeda:

  • Properti FirstName harus memiliki panjang yang lebih besar dari nol (dan tidak boleh hanya terdiri dari spasi)
  • Properti LastName harus memiliki panjang yang lebih besar dari nol (dan tidak boleh hanya terdiri dari spasi)
  • Jika properti Telepon memiliki nilai (memiliki panjang lebih besar dari 0) maka properti Telepon harus cocok dengan ekspresi reguler.
  • Jika properti Email memiliki nilai (memiliki panjang lebih besar dari 0) maka properti Email harus cocok dengan ekspresi reguler.

Ketika ada pelanggaran aturan validasi, pesan kesalahan ditambahkan ke ModelState dengan bantuan metode AddModelError(). Saat Anda menambahkan pesan ke ModelState, Anda memberikan nama properti dan teks pesan kesalahan validasi. Pesan kesalahan ini ditampilkan dalam tampilan oleh metode pembantu Html.ValidationSummary() dan Html.ValidationMessage().

Setelah aturan validasi dijalankan, properti IsValid dari ModelState dicentang. Properti IsValid mengembalikan false ketika pesan kesalahan validasi telah ditambahkan ke ModelState. Jika validasi gagal, formulir Buat diputar ulang dengan pesan kesalahan.

Catatan

Saya mendapatkan ekspresi reguler untuk memvalidasi nomor telepon dan alamat email dari repositori regex di http://regexlib.com

Menambahkan Logika Validasi ke Tindakan Edit

Tindakan Edit() memperbarui Kontak. Tindakan Edit() perlu melakukan validasi yang sama persis dengan tindakan Create(). Alih-alih menduplikasi kode validasi yang sama, kita harus merefaktor pengontrol Kontak sehingga tindakan Create() dan Edit() memanggil metode validasi yang sama.

Kelas Pengontrol Kontak yang dimodifikasi terkandung dalam Daftar 3. Kelas ini memiliki metode ValidateContact() baru yang dipanggil dalam tindakan Create() dan Edit().

Daftar 3 - Controllers\ContactController.vb

Public Class ContactController
    Inherits System.Web.Mvc.Controller

    Private _entities As New ContactManagerDBEntities()

    Protected Sub ValidateContact(contactToValidate As Contact)
        If contactToValidate.FirstName.Trim().Length = 0 Then
            ModelState.AddModelError("FirstName", "First name is required.")
        End If
        If contactToValidate.LastName.Trim().Length = 0 Then
            ModelState.AddModelError("LastName", "Last name is required.")
        End If
        If (contactToValidate.Phone.Length > 0 AndAlso Not Regex.IsMatch(contactToValidate.Phone, "((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))
            ModelState.AddModelError("Phone", "Invalid phone number.")
        End If        
        If (contactToValidate.Email.Length > 0 AndAlso  Not Regex.IsMatch(contactToValidate.Email, "^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
            ModelState.AddModelError("Email", "Invalid email address.")
        End If
    End Sub

    '
    ' GET: /Contact

    Function Index() As ActionResult
        Return View(_entities.ContactSet.ToList())
    End Function

    '
    ' GET: /Contact/Create

    Function Create() As ActionResult
        Return View()
    End Function

    '
    ' POST: /Contact/Create

    <AcceptVerbs(HttpVerbs.Post)> _
    Function Create(<Bind(Exclude:="Id")> ByVal contactToCreate As Contact) As ActionResult
        ' Validation logic
        ValidateContact(contactToCreate)
        If Not ModelState.IsValid Then
            Return View()
        End If

        ' Database logic
        Try
            _entities.AddToContactSet(contactToCreate)
            _entities.SaveChanges()
            Return RedirectToAction("Index")
        Catch
            Return View()
        End Try
    End Function

    '
    ' GET: /Contact/Edit/5

    Function Edit(ByVal id As Integer) As ActionResult
        Dim contactToEdit = (from c in _entities.ContactSet _
                           where c.Id = id _
                           select c).FirstOrDefault()

        Return View(contactToEdit)
    End Function

    '
    ' POST: /Contact/Edit/5

    <AcceptVerbs(HttpVerbs.Post)> _
    Function Edit(ByVal contactToEdit As Contact) As ActionResult
        ' Validation logic
        ValidateContact(contactToEdit)
        If Not ModelState.IsValid Then
            Return View()
        End If

        ' Database logic
        Try
            Dim originalContact = (from c in _entities.ContactSet _
                             where c.Id = contactToEdit.Id _
                             select c).FirstOrDefault()
            _entities.ApplyPropertyChanges(originalContact.EntityKey.EntitySetName, contactToEdit)
            _entities.SaveChanges()
            Return RedirectToAction("Index")
        Catch
            Return View()
        End Try
    End Function

    '
    ' GET: /Contact/Delete/5

    Function Delete(ByVal id As Integer) As ActionResult
        Dim contactToDelete = (from c in _entities.ContactSet _
                           where c.Id = id _
                           select c).FirstOrDefault()

        Return View(contactToDelete)
    End Function

    '
    ' POST: /Contact/Delete/5

    <AcceptVerbs(HttpVerbs.Post)> _
    Function Delete(ByVal contactToDelete As Contact) As ActionResult
        Try
            Dim originalContact = (from c in _entities.ContactSet _
                             where c.Id = contactToDelete.Id _
                             select c).FirstOrDefault()
            _entities.DeleteObject(originalContact)
            _entities.SaveChanges()
            Return RedirectToAction("Index")
        Catch
            Return View()
        End Try
    End Function

End Class

Ringkasan

Dalam perulangan ini, kami menambahkan validasi formulir dasar ke aplikasi Contact Manager kami. Logika validasi kami mencegah pengguna mengirimkan kontak baru atau mengedit kontak yang ada tanpa menyediakan nilai untuk properti FirstName dan LastName. Selain itu, pengguna harus menyediakan nomor telepon dan alamat email yang valid.

Dalam iterasi ini, kami menambahkan logika validasi ke aplikasi Contact Manager kami dengan cara termampatkan. Namun, mencampur logika validasi kami ke dalam logika pengontrol kami akan menciptakan masalah bagi kami dalam jangka panjang. Aplikasi kami akan lebih sulit untuk dipertahankan dan dimodifikasi dari waktu ke waktu.

Dalam iterasi berikutnya, kami akan merefaktor logika validasi dan logika akses database kami dari pengontrol kami. Kami akan memanfaatkan beberapa prinsip desain perangkat lunak untuk memungkinkan kami membuat aplikasi yang lebih longgar dan lebih dapat dipertahankan.