Bagikan melalui


Menangani Pengecualian di Tingkat BLL (Business Logic Layer) dan DAL (Data Access Layer) pada Halaman ASP.NET (C#)

oleh Scott Mitchell

Unduh PDF

Dalam tutorial ini kita akan melihat cara menampilkan pesan kesalahan yang ramah dan informatif jika terjadi pengecualian selama operasi sisipkan, perbarui, atau hapus kontrol Web data ASP.NET.

Pendahuluan

Bekerja dengan data dari aplikasi web ASP.NET menggunakan arsitektur aplikasi berjenjang melibatkan tiga langkah umum berikut:

  1. Tentukan metode Lapisan Logika Bisnis apa yang perlu dipanggil dan nilai parameter apa yang akan diteruskannya. Nilai parameter dapat dikodekan secara permanen, ditetapkan secara terprogram, atau input yang dimasukkan oleh pengguna.
  2. Panggil metode .
  3. Proses hasilnya. Saat memanggil metode BLL yang mengembalikan data, ini mungkin melibatkan pengikatan data ke kontrol Web data. Untuk metode BLL yang memodifikasi data, ini mungkin termasuk melakukan beberapa tindakan berdasarkan nilai pengembalian atau menangani pengecualian apa pun yang muncul di Langkah 2.

Seperti yang kita lihat di tutorial sebelumnya, kontrol ObjectDataSource dan Web data memberikan titik ekstensibilitas untuk Langkah 1 dan 3. GridView, misalnya, mengaktifkan peristiwanya RowUpdating sebelum menetapkan nilai bidangnya ke koleksi ObjectDataSource-nya UpdateParameters ; peristiwanya RowUpdated dimunculkan setelah ObjectDataSource menyelesaikan operasi.

Kami telah menganalisis event yang terjadi selama Langkah 1 dan memahami cara menggunakan event tersebut untuk menyesuaikan parameter input atau membatalkan operasi. Dalam tutorial ini kita akan mengalihkan perhatian kita pada peristiwa yang terjadi setelah operasi selesai. Dengan penanganan aktivitas pasca-tingkat ini kita dapat, antara lain, menentukan apakah pengecualian terjadi selama operasi dan menanganinya dengan anggun, menampilkan pesan kesalahan informatif yang ramah di layar daripada default ke halaman pengecualian ASP.NET standar.

Untuk mengilustrasikan bekerja dengan peristiwa pasca-tingkat ini, mari kita buat halaman yang mencantumkan produk dalam GridView yang dapat diedit. Saat memperbarui produk, jika pengecualian dimunculkan, halaman ASP.NET kami akan menampilkan pesan singkat di atas GridView yang menjelaskan bahwa masalah telah terjadi. Mari kita mulai!

Langkah 1: Membuat GridView Produk yang Dapat Diedit

Dalam tutorial sebelumnya kami membuat GridView yang dapat diedit hanya dengan dua bidang, ProductName dan UnitPrice. Ini diperlukan untuk membuat kelebihan beban tambahan untuk ProductsBLL metode kelas UpdateProduct , yang hanya menerima tiga parameter input (nama produk, harga satuan, dan ID) dibandingkan dengan parameter untuk setiap bidang produk. Untuk tutorial ini, mari kita berlatih teknik ini lagi, membuat GridView yang dapat diedit yang menampilkan nama produk, kuantitas per unit, harga satuan, dan unit dalam stok, tetapi hanya memungkinkan nama, harga unit, dan unit dalam stok untuk diedit.

Untuk mengakomodasi skenario ini, kita akan memerlukan overload lain dari metode UpdateProduct, yang menerima empat parameter: nama produk, harga satuan, unit yang tersedia, dan ID. Tambahkan metode berikut ke ProductsBLL kelas :

[System.ComponentModel.DataObjectMethodAttribute(
    System.ComponentModel.DataObjectMethodType.Update, false)]
public bool UpdateProduct(string productName, decimal? unitPrice, short? unitsInStock,
    int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;
    Northwind.ProductsRow product = products[0];
    product.ProductName = productName;
    if (unitPrice == null) product.SetUnitPriceNull();
      else product.UnitPrice = unitPrice.Value;
    if (unitsInStock == null) product.SetUnitsInStockNull();
      else product.UnitsInStock = unitsInStock.Value;
    // Update the product record
    int rowsAffected = Adapter.Update(product);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

Dengan metode ini selesai, kami siap untuk membuat halaman ASP.NET yang memungkinkan untuk mengedit empat bidang produk tertentu ini. ErrorHandling.aspx Buka halaman di EditInsertDelete folder dan tambahkan GridView ke halaman melalui Perancang. Ikatkan GridView ke ObjectDataSource baru, dengan memetakan metode Select() ke dalam kelas ProductsBLL yang metodenya GetProducts() dan memetakan metode Update() ke overload UpdateProduct yang baru saja dibuat.

Gunakan Metode Overload UpdateProduct yang Menerima Empat Parameter Input

Gambar 1: Gunakan UpdateProduct Metode Kelebihan Beban yang Menerima Empat Parameter Input (Klik untuk melihat gambar ukuran penuh)

Ini akan membuat ObjectDataSource dengan koleksi UpdateParameters yang memiliki empat parameter dan GridView dengan masing-masing bidang untuk setiap produk. Markup deklaratif ObjectDataSource menetapkan properti OldValuesParameterFormatString dengan nilai original_{0}, yang akan menyebabkan kegagalan karena kelas BLL kami tidak memerlukan parameter input bernama original_productID yang akan diteruskan. Jangan lupa untuk menghapus pengaturan ini sama sekali dari sintaks deklaratif (atau atur ke nilai default, {0}).

Selanjutnya, kurangi GridView untuk hanya menyertakan ProductName, QuantityPerUnit, UnitPrice, dan UnitsInStock BoundFields. Jangan ragu untuk menerapkan pemformatan tingkat bidang apa pun yang Anda anggap perlu (seperti mengubah properti HeaderText).

Dalam tutorial sebelumnya kita melihat cara memformat UnitPrice BoundField sebagai mata uang baik dalam mode baca-saja maupun mode edit. Mari kita lakukan hal yang sama di sini. Ingat bahwa ini memerlukan pengaturan properti BoundField DataFormatString ke {0:c}, propertinya HtmlEncode ke false, dan ApplyFormatInEditMode ke true, seperti yang ditunjukkan pada Gambar 2.

Mengonfigurasi UnitPrice BoundField untuk Ditampilkan sebagai Mata Uang

Gambar 2: Konfigurasikan UnitPrice BoundField untuk Ditampilkan sebagai Mata Uang (Klik untuk melihat gambar ukuran penuh)

Memformat UnitPrice sebagai mata uang di antarmuka pengeditan mengharuskan pembuatan penangan peristiwa pada RowUpdating GridView yang menganalisis string berformat mata uang menjadi nilai decimal. Ingat bahwa penanganan RowUpdating aktivitas dari tutorial terakhir juga diperiksa untuk memastikan bahwa pengguna memberikan UnitPrice nilai. Namun, untuk tutorial ini mari kita izinkan pengguna untuk menghilangkan harga.

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    if (e.NewValues["UnitPrice"] != null)
        e.NewValues["UnitPrice"] =decimal.Parse(e.NewValues["UnitPrice"].ToString(),
            System.Globalization.NumberStyles.Currency);
}

GridView kami mencakup QuantityPerUnit BoundField, tetapi BoundField ini seharusnya hanya untuk tujuan tampilan dan tidak boleh diedit oleh pengguna. Untuk mengatur ini, cukup atur properti BoundFields ReadOnly ke true.

Jadikan QuantityPerUnit BoundField Hanya Baca

Gambar 3: Buat QuantityPerUnit BoundField Read-Only (Klik untuk melihat gambar ukuran penuh)

Terakhir, centang kotak Aktifkan Pengeditan dari tag pintar GridView. Setelah langkah-langkah ini selesai dilakukan, Desainer Halaman ErrorHandling.aspx seharusnya terlihat mirip dengan Gambar 4.

Hapus Semua Kecuali BoundFields yang Dibutuhkan dan Centang Kotak untuk Mengaktifkan Pengeditan

Gambar 4: Hapus Semua BoundFields Kecuali yang Diperlukan dan Centang Kotak Aktifkan Pengeditan (Klik untuk melihat gambar ukuran penuh)

Pada titik ini, kita memiliki daftar semua bidang produk ProductName, QuantityPerUnit, UnitPrice, dan UnitsInStock; namun, hanya bidang ProductName, UnitPrice, dan UnitsInStock yang dapat diedit.

Pengguna Sekarang Dapat Dengan Mudah Mengedit Nama, Harga, dan Unit Produk Di Bidang Stok

Gambar 5: Pengguna Sekarang Dapat Dengan Mudah Mengedit Nama, Harga, dan Unit Produk Di Bidang Stok (Klik untuk melihat gambar ukuran penuh)

Langkah 2: Menangani Pengecualian DAL-Level dengan Anggun

Meskipun GridView kami yang dapat diedit berfungsi dengan baik ketika pengguna memasukkan nilai yang valid untuk nama, harga, dan unit dalam stok dari produk yang diedit, memasukkan nilai yang tidak valid akan menghasilkan pengecualian. Misalnya, menghilangkan nilai ProductName akan menyebabkan NoNullAllowedException dilemparkan karena properti ProductName di kelas ProductsRow memiliki propertinya AllowDBNull diatur ke false; jika database mengalami kegagalan, SqlException akan dilemparkan oleh TableAdapter saat mencoba menyambung ke database. Tanpa mengambil tindakan apa pun, pengecualian ini muncul dari Lapisan Akses Data ke Lapisan Logika Bisnis, lalu ke halaman ASP.NET, dan akhirnya ke runtime ASP.NET.

Bergantung pada bagaimana aplikasi web Anda dikonfigurasi dan apakah Anda mengunjungi aplikasi dari localhost, pengecualian yang tidak tertangani dapat mengakibatkan halaman kesalahan server generik, laporan kesalahan terperinci, atau halaman web yang mudah digunakan. Lihat Penanganan Kesalahan Aplikasi Web di ASP.NET dan Elemen CustomErrors untuk informasi selengkapnya tentang bagaimana runtime ASP.NET merespons pengecualian yang tidak tertangkap.

Gambar 6 menunjukkan layar yang ditemui saat mencoba memperbarui produk tanpa menentukan nilainya ProductName . Ini adalah laporan kesalahan terperinci default yang ditampilkan saat masuk melalui localhost.

Menghilangkan Nama Produk Akan Menampilkan Detail Pengecualian

Gambar 6: Menghilangkan Nama Produk Akan Menampilkan Detail Pengecualian (Klik untuk melihat gambar ukuran penuh)

Meskipun detail pengecualian tersebut berguna saat menguji aplikasi, menyajikan layar seperti itu kepada pengguna akhir saat terjadi pengecualian adalah tidak ideal. Pengguna akhir kemungkinan tidak tahu apa NoNullAllowedException itu atau mengapa itu disebabkan. Pendekatan yang lebih baik adalah menyajikan pesan yang lebih ramah pengguna kepada pengguna yang menjelaskan bahwa ada masalah saat mencoba memperbarui produk.

Jika pengecualian terjadi saat melakukan operasi, peristiwa tingkat pasca-operasi di dalam ObjectDataSource dan kontrol data Web menyediakan sarana untuk mendeteksi pengecualian tersebut dan mencegahnya agar tidak menyebar ke runtime ASP.NET. Misalnya, mari kita buat penanganan aktivitas untuk peristiwa GridView RowUpdated yang menentukan apakah pengecualian telah diaktifkan dan, jika demikian, menampilkan detail pengecualian dalam kontrol Web Label.

Mulailah dengan menambahkan Label ke halaman ASP.NET, mengatur propertinya ID ke ExceptionDetails dan menghapus propertinya Text . Untuk menarik mata pengguna ke pesan ini, atur propertinya CssClass ke Warning, yang merupakan kelas CSS yang kami tambahkan ke Styles.css file di tutorial sebelumnya. Ingat bahwa kelas CSS ini menyebabkan teks Label ditampilkan dalam font merah, miring, tebal, ekstra besar.

Menambahkan Kontrol Web Label ke Halaman

Gambar 7: Tambahkan Kontrol Web Label ke Halaman (Klik untuk melihat gambar ukuran penuh)

Karena kami ingin kontrol Web Label ini terlihat hanya segera setelah pengecualian terjadi, atur propertinya Visible ke false di Page_Load penanganan aktivitas:

protected void Page_Load(object sender, EventArgs e)
{
    ExceptionDetails.Visible = false;
}

Dengan kode ini, pada kunjungan pertama ke halaman dan postback berikutnya, kontrol ExceptionDetails akan memiliki properti Visible diatur ke false. Dalam menghadapi pengecualian tingkat DAL atau BLL, yang dapat kita deteksi di penanganan aktivitas GridView RowUpdated , kita akan mengatur ExceptionDetails properti kontrol Visible ke true. Karena penanganan peristiwa kontrol Web terjadi setelah penanganan peristiwa Page_Load dalam siklus halaman, Label akan ditampilkan. Namun, pada postback berikutnya, pengendali acara Page_Load akan mengubah properti Visible kembali ke false, menyembunyikannya dari pandangan.

Nota

Atau, kita dapat menghapus kebutuhan untuk mengatur properti ExceptionDetails dari kontrol dengan menetapkan propertinya Visible menjadi Page_Load dalam sintaks deklaratif dan menonaktifkan status tampilannya dengan mengatur propertinya Visible ke false di EnableViewState. Kami akan menggunakan pendekatan alternatif ini dalam tutorial mendatang.

Dengan kontrol Label ditambahkan, langkah kami selanjutnya adalah membuat penanganan aktivitas untuk acara GridView RowUpdated . Pilih GridView di Perancang, buka jendela Properti, dan klik ikon petir, yang mencantumkan peristiwa GridView. Seharusnya sudah ada entri di sana untuk peristiwa GridView RowUpdating, karena kami telah membuat penanganan peristiwa untuk peristiwa ini sebelumnya dalam tutorial ini. Buat penanganan acara untuk event RowUpdated juga.

Membuat Pengendali Acara untuk Peristiwa RowUpdated GridView

Gambar 8: Membuat Penanganan Aktivitas untuk Peristiwa GridView RowUpdated

Nota

Anda juga dapat membuat penanganan aktivitas melalui daftar drop-down di bagian atas file kelas code-behind. Pilih GridView dari menu tarik-turun di sebelah kiri dan RowUpdated event dari yang ada di sebelah kanan.

Membuat penanganan aktivitas ini akan menambahkan kode berikut ke kelas code-behind halaman ASP.NET:

protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
}

Parameter input kedua penanganan aktivitas ini adalah objek jenis GridViewUpdatedEventArgs, yang memiliki tiga properti yang menarik untuk menangani pengecualian:

  • Exception referensi ke pengecualian yang dilemparkan; jika tidak ada pengecualian yang dilemparkan, properti ini akan memiliki nilai null
  • ExceptionHandled nilai Boolean yang menunjukkan apakah pengecualian ditangani di RowUpdated penangan kejadian atau tidak; jika false (default), pengecualian dilemparkan kembali, menjalar hingga ke runtime ASP.NET
  • KeepInEditMode jika diatur ke true baris GridView yang diedit tetap dalam mode edit; jika false (default), baris GridView kembali ke mode baca-saja

Kode kami kemudian harus memeriksa apakah Exception tidak sama dengan null, yang berarti bahwa terjadi pengecualian saat melakukan operasi. Jika demikian, kami ingin:

  • Menampilkan pesan yang mudah digunakan di ExceptionDetails Label
  • Menunjukkan bahwa pengecualian telah ditangani
  • Pertahankan baris GridView dalam mode edit

Kode berikut ini menyelesaikan tujuan ini:

protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
    if (e.Exception != null)
    {
        // Display a user-friendly message
        ExceptionDetails.Visible = true;
        ExceptionDetails.Text = "There was a problem updating the product. ";
        if (e.Exception.InnerException != null)
        {
            Exception inner = e.Exception.InnerException;
            if (inner is System.Data.Common.DbException)
                ExceptionDetails.Text +=
                    "Our database is currently experiencing problems." +
                    "Please try again later.";
            else if (inner is NoNullAllowedException)
                ExceptionDetails.Text +=
                    "There are one or more required fields that are missing.";
            else if (inner is ArgumentException)
            {
                string paramName = ((ArgumentException)inner).ParamName;
                ExceptionDetails.Text +=
                    string.Concat("The ", paramName, " value is illegal.");
            }
            else if (inner is ApplicationException)
                ExceptionDetails.Text += inner.Message;
        }
        // Indicate that the exception has been handled
        e.ExceptionHandled = true;
        // Keep the row in edit mode
        e.KeepInEditMode = true;
    }
}

Penanganan aktivitas ini dimulai dengan memeriksa untuk melihat apakah e.Exception adalah null. Jika tidak, properti ExceptionDetails Label Visible diatur ke true dan properti Text diatur ke "Ada masalah saat memperbarui produk." Detail dari pengecualian aktual yang dilemparkan terdapat dalam properti objek e.ExceptionInnerException. Pengecualian internal ini diperiksa dan, jika merupakan jenis tertentu, pesan tambahan yang bermanfaat ditambahkan ke properti Label ExceptionDetails. Terakhir, ExceptionHandled dan KeepInEditMode adalah properti yang keduanya diatur ke true.

Gambar 9 menunjukkan cuplikan layar halaman ini saat menghilangkan nama produk; Gambar 10 menunjukkan hasil saat memasukkan nilai ilegal UnitPrice (-50).

ProductName BoundField Harus Berisi Nilai

Gambar 9: ProductName BoundField Harus Berisi Nilai (Klik untuk melihat gambar ukuran penuh)

Nilai UnitPrice Negatif Tidak Diizinkan

Gambar 10: Nilai Negatif UnitPrice Tidak Diizinkan (Klik untuk melihat gambar ukuran penuh)

Dengan mengatur properti e.ExceptionHandled ke true, pengendali acara RowUpdated telah menunjukkan bahwa ia telah menangani pengecualian. Oleh karena itu, pengecualian tidak akan menyebar hingga runtime ASP.NET.

Nota

Gambar 9 dan 10 menunjukkan cara yang anggun untuk menangani pengecualian yang dimunculkan karena input pengguna yang tidak valid. Namun, idealnya, input yang tidak valid tersebut tidak akan pernah mencapai Lapisan Logika Bisnis sejak awal, karena halaman ASP.NET harus memastikan bahwa input pengguna tersebut valid sebelum memanggil metode kelas ProductsBLLUpdateProduct. Dalam tutorial berikutnya, kita akan melihat cara menambahkan kontrol validasi ke antarmuka pengeditan dan penyisipan untuk memastikan bahwa data yang dikirimkan ke Lapisan Logika Bisnis sesuai dengan aturan bisnis. Kontrol validasi tidak hanya mencegah pemanggilan UpdateProduct metode sampai data yang disediakan pengguna valid, tetapi juga memberikan pengalaman pengguna yang lebih informatif untuk mengidentifikasi masalah entri data.

Langkah 3: Menangani Pengecualian BLL-Level dengan Anggun

Saat menyisipkan, memperbarui, atau menghapus data, Lapisan Akses Data dapat melemparkan pengecualian dalam menghadapi kesalahan terkait data. Database mungkin offline, kolom tabel database yang diperlukan mungkin tidak memiliki nilai yang ditentukan, atau batasan tingkat tabel mungkin telah dilanggar. Selain pengecualian terkait data secara ketat, Lapisan Logika Bisnis dapat menggunakan pengecualian untuk menunjukkan kapan aturan bisnis telah dilanggar. Dalam tutorial Membuat Lapisan Logika Bisnis , misalnya, kami menambahkan pemeriksaan aturan bisnis ke kelebihan beban asli UpdateProduct . Secara khusus, jika pengguna menandai produk sebagai dihentikan, kami mengharuskan produk tersebut bukan satu-satunya yang disediakan oleh pemasoknya. Jika kondisi ini dilanggar, sebuah ApplicationException dilemparkan.

UpdateProduct Untuk overload yang dibuat dalam tutorial ini, mari kita tambahkan aturan bisnis yang melarang perubahan nilai UnitPrice menjadi nilai baru yang lebih dari dua kali dari nilai awalnya. Untuk mencapai hal ini, sesuaikan UpdateProduct kelebihan beban sehingga melakukan pemeriksaan ini dan melempar ApplicationException jika aturan dilanggar. Metode yang diperbarui mengikuti:

public bool UpdateProduct(string productName, decimal? unitPrice, short? unitsInStock,
    int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;
    Northwind.ProductsRow product = products[0];
    // Make sure the price has not more than doubled
    if (unitPrice != null && !product.IsUnitPriceNull())
        if (unitPrice > product.UnitPrice * 2)
          throw new ApplicationException(
            "When updating a product price," +
            " the new price cannot exceed twice the original price.");
    product.ProductName = productName;
    if (unitPrice == null) product.SetUnitPriceNull();
      else product.UnitPrice = unitPrice.Value;
    if (unitsInStock == null) product.SetUnitsInStockNull();
      else product.UnitsInStock = unitsInStock.Value;
    // Update the product record
    int rowsAffected = Adapter.Update(product);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

Dengan perubahan ini, setiap pembaruan harga yang lebih dari dua kali harga yang ada akan menyebabkan ApplicationException dilemparkan. Sama seperti pengecualian yang dimunculkan dari DAL, yang dinaikkan ApplicationException BLL ini dapat dideteksi dan ditangani di penanganan aktivitas GridView RowUpdated . Bahkan, kode penanganan kejadian RowUpdated, seperti yang tertulis, akan mendeteksi pengecualian ini dengan benar dan menampilkan nilai properti ApplicationExceptionMessage. Gambar 11 menunjukkan cuplikan layar ketika pengguna mencoba memperbarui harga Chai menjadi $50,00, yang lebih dari dua kali lipat harganya saat ini sebesar $19,95.

Aturan Bisnis Melarang Kenaikan Harga Yang Lebih dari Dua Kali Lipat Harga Produk

Gambar 11: Aturan Bisnis Melarang Kenaikan Harga Yang Lebih dari Dua Kali Lipat Harga Produk (Klik untuk melihat gambar ukuran penuh)

Nota

Idealnya aturan logika bisnis kami akan direfaktor dari UpdateProduct metode kelebihan beban dan ke dalam metode umum. Ini dibiarkan sebagai latihan untuk pembaca.

Ringkasan

Selama operasi penyisipan, pembaruan, dan penghapusan, kontrol Web data dan ObjectDataSource yang terlibat menimbulkan peristiwa sebelum dan sesudah tingkat yang mengapit operasi aktual. Seperti yang kita lihat dalam tutorial ini dan yang sebelumnya, ketika bekerja dengan GridView yang dapat diedit, peristiwa GridView RowUpdating diaktifkan, diikuti oleh peristiwa ObjectDataSource Updating, di mana perintah pembaruan dilakukan pada objek dasar ObjectDataSource. Setelah operasi selesai, event ObjectDataSource Updated diaktifkan, diikuti oleh event GridView RowUpdated.

Kita dapat membuat penanganan aktivitas untuk peristiwa pra-tingkat untuk menyesuaikan parameter input atau untuk peristiwa pasca-tingkat untuk memeriksa dan menanggapi hasil operasi. Pelaksana kejadian pada tingkat akhir paling umum digunakan untuk mendeteksi adanya pengecualian selama operasi. Dalam menghadapi pengecualian, penanganan aktivitas pasca-tingkat ini dapat secara opsional menangani pengecualian sendiri. Dalam tutorial ini kita melihat cara menangani pengecualian seperti itu dengan menampilkan pesan kesalahan yang ramah.

Dalam tutorial berikutnya kita akan melihat cara mengurangi kemungkinan pengecualian yang timbul dari masalah pemformatan data (seperti memasukkan negatif UnitPrice). Secara khusus, kita akan melihat cara menambahkan kontrol validasi ke antarmuka pengeditan dan penyisipan.

Selamat Pemrograman!

Tentang Penulis

Scott Mitchell, penulis tujuh buku ASP/ASP.NET dan pendiri 4GuysFromRolla.com, telah bekerja sama dengan teknologi Microsoft Web sejak 1998. Scott bekerja sebagai konsultan, pelatih, dan penulis independen. Buku terbarunya adalah Sams Teach Yourself ASP.NET 2.0 dalam 24 Jam. Dia dapat dijangkau di mitchell@4GuysFromRolla.com.

Ucapan terima kasih khusus kepada

Seri tutorial ini ditinjau oleh banyak peninjau yang bermanfaat. Peninjau utama untuk tutorial ini adalah Liz Shulok. Tertarik untuk meninjau artikel MSDN saya yang akan datang? Jika demikian, hubungi saya di mitchell@4GuysFromRolla.com.