Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini memperlihatkan cara membuat anotasi model Anda, menggunakan anotasi untuk validasi data, dan menangani kesalahan validasi di API web Anda. Saat klien mengirim data ke API web Anda, sering kali Anda ingin memvalidasi data sebelum melakukan pemrosesan apa pun.
Anotasi Data
Di ASP.NET Web API, Anda dapat menggunakan atribut dari namespace System.ComponentModel.DataAnnotations untuk mengatur aturan validasi untuk properti pada model Anda. Pertimbangkan model berikut:
using System.ComponentModel.DataAnnotations;
namespace MyApi.Models
{
public class Product
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public decimal Price { get; set; }
[Range(0, 999)]
public double Weight { get; set; }
}
}
Jika Anda telah menggunakan validasi model di ASP.NET MVC, ini akan terlihat akrab. Atribut Wajib mengatakan bahwa Name
properti tidak boleh null. Atribut Range mengatakan bahwa Weight
harus antara nol dan 999.
Misalkan klien mengirim permintaan POST dengan representasi JSON berikut:
{ "Id":4, "Price":2.99, "Weight":5 }
Anda dapat melihat bahwa klien tidak menyertakan Name
properti , yang ditandai sebagai diperlukan. Ketika Web API mengonversi JSON menjadi Product
instans Product
, api tersebut memvalidasi terhadap atribut validasi. Dalam tindakan pengontrol, Anda dapat memeriksa apakah model valid:
using MyApi.Models;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace MyApi.Controllers
{
public class ProductsController : ApiController
{
public HttpResponseMessage Post(Product product)
{
if (ModelState.IsValid)
{
// Do something with the product (not shown).
return new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
}
}
Validasi model tidak menjamin bahwa data klien aman. Validasi tambahan mungkin diperlukan di lapisan lain aplikasi. (Misalnya, lapisan data mungkin memberlakukan batasan kunci asing.) Tutorial Menggunakan WEB API dengan Entity Framework mengeksplorasi beberapa masalah ini.
"Under-Posting": Under-posting terjadi ketika klien meninggalkan beberapa properti. Misalnya, klien mengirimkan hal berikut:
{"Id":4, "Name":"Gizmo"}
Di sini, klien tidak menentukan nilai untuk Price
atau Weight
. Formatter JSON menetapkan nilai default nol ke properti yang hilang.
Status model valid, karena nol adalah nilai yang valid untuk properti ini. Apakah ini masalah tergantung pada skenario Anda. Misalnya, dalam operasi pembaruan, Anda mungkin ingin membedakan antara "nol" dan "tidak diatur." Untuk memaksa klien menetapkan nilai, buat properti dapat diubah ke null dan atur atribut Wajib :
[Required]
public decimal? Price { get; set; }
"Over-Posting": Klien juga dapat mengirim lebih banyak data dari yang Anda harapkan. Contohnya:
{"Id":4, "Name":"Gizmo", "Color":"Blue"}
Di sini, JSON menyertakan properti ("Warna") yang tidak ada dalam Product
model. Dalam hal ini, formatter JSON hanya mengabaikan nilai ini. (Pemformat XML melakukan hal yang sama.) Postingan berlebih menyebabkan masalah jika model Anda memiliki properti yang Ingin Anda baca-saja. Contohnya:
public class UserProfile
{
public string Name { get; set; }
public Uri Blog { get; set; }
public bool IsAdmin { get; set; } // uh-oh!
}
Anda tidak ingin pengguna memperbarui IsAdmin
properti dan meningkatkan diri mereka ke administrator! Strategi paling aman adalah menggunakan kelas model yang sama persis dengan apa yang diizinkan untuk dikirim klien:
public class UserProfileDTO
{
public string Name { get; set; }
public Uri Blog { get; set; }
// Leave out "IsAdmin"
}
Catatan
Posting blog Brad Wilson "Validasi Input vs Validasi Model di ASP.NET MVC" memiliki diskusi yang baik tentang under-posting dan over-posting. Meskipun postingan tersebut tentang ASP.NET MVC 2, masalahnya masih relevan dengan Web API.
Menangani Kesalahan Validasi
WEB API tidak secara otomatis mengembalikan kesalahan ke klien saat validasi gagal. Terserah tindakan pengontrol untuk memeriksa status model dan merespons dengan tepat.
Anda juga dapat membuat filter tindakan untuk memeriksa status model sebelum tindakan pengontrol dipanggil. Kode berikut menunjukkan contoh:
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Http.ModelBinding;
namespace MyApi.Filters
{
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ModelState.IsValid == false)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(
HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
}
}
Jika validasi model gagal, filter ini mengembalikan respons HTTP yang berisi kesalahan validasi. Dalam hal ini, tindakan pengontrol tidak dipanggil.
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Date: Tue, 16 Jul 2013 21:02:29 GMT
Content-Length: 331
{
"Message": "The request is invalid.",
"ModelState": {
"product": [
"Required property 'Name' not found in JSON. Path '', line 1, position 17."
],
"product.Name": [
"The Name field is required."
],
"product.Weight": [
"The field Weight must be between 0 and 999."
]
}
}
Untuk menerapkan filter ini ke semua pengontrol API Web, tambahkan instans filter ke koleksi HttpConfiguration.Filters selama konfigurasi:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ValidateModelAttribute());
// ...
}
}
Opsi lain adalah mengatur filter sebagai atribut pada pengontrol individual atau tindakan pengontrol:
public class ProductsController : ApiController
{
[ValidateModel]
public HttpResponseMessage Post(Product product)
{
// ...
}
}