Saya memiliki kekhawatiran tentang cara kami mengembalikan kesalahan ke klien.
Apakah kami segera mengembalikan kesalahan dengan melemparkan HttpResponseException ketika kami mendapatkan kesalahan:
public void Post(Customer customer)
{
if (string.IsNullOrEmpty(customer.Name))
{
throw new HttpResponseException("Customer Name cannot be empty", HttpStatusCode.BadRequest)
}
if (customer.Accounts.Count == 0)
{
throw new HttpResponseException("Customer does not have any account", HttpStatusCode.BadRequest)
}
}
Atau kami mengakumulasikan semua kesalahan kemudian mengirim kembali ke klien:
public void Post(Customer customer)
{
List<string> errors = new List<string>();
if (string.IsNullOrEmpty(customer.Name))
{
errors.Add("Customer Name cannot be empty");
}
if (customer.Accounts.Count == 0)
{
errors.Add("Customer does not have any account");
}
var responseMessage = new HttpResponseMessage<List<string>>(errors, HttpStatusCode.BadRequest);
throw new HttpResponseException(responseMessage);
}
Ini hanya kode sampel, tidak masalah kesalahan validasi atau kesalahan server, saya hanya ingin tahu praktik terbaik, pro dan kontra dari setiap pendekatan.
c#
rest
asp.net-web-api
cuongle
sumber
sumber
ModelState
.HttpResponseException
kelas yang mengambil dua parameter yang disebutkan dalam posting Anda -HttpResponseException("Customer Name cannot be empty", HttpStatusCode.BadRequest)
yaituHttpResponseException(string, HttpStatusCode)
Jawaban:
Bagi saya, saya biasanya mengirim kembali
HttpResponseException
dan mengatur kode status sesuai tergantung pada pengecualian yang dilemparkan dan jika pengecualian itu fatal atau tidak akan menentukan apakah sayaHttpResponseException
segera mengirim kembali .Pada akhirnya, ini adalah API yang mengirim kembali respons dan bukan tampilan, jadi saya pikir tidak apa-apa untuk mengirim kembali pesan dengan pengecualian dan kode status ke konsumen. Saat ini saya tidak perlu mengumpulkan kesalahan dan mengirimnya kembali karena sebagian besar pengecualian biasanya karena parameter atau panggilan yang salah, dll
Contoh di aplikasi saya adalah bahwa kadang-kadang klien akan meminta data, tetapi tidak ada data yang tersedia jadi saya melempar kustom
NoDataAvailableException
dan membiarkannya menggelembung ke aplikasi Web API, di mana kemudian di filter kustom saya yang menangkapnya mengirim kembali pesan yang relevan bersama dengan kode status yang benar.Saya tidak 100% yakin tentang apa praktik terbaik untuk ini, tetapi ini bekerja untuk saya saat ini sehingga itulah yang saya lakukan.
Perbarui :
Sejak saya menjawab pertanyaan ini, beberapa posting blog telah ditulis pada topik:
https://weblogs.asp.net/fredriknormen/asp-net-web-api-exception-handling
(Yang ini memiliki beberapa fitur baru di build malam) https://docs.microsoft.com/archive/blogs/youssefm/error-handling-in-asp-net-webapi
Perbarui 2
Pembaruan untuk proses penanganan kesalahan kami, kami memiliki dua kasus:
Untuk kesalahan umum seperti tidak ditemukan, atau parameter tidak valid diteruskan ke tindakan, kami mengembalikan a
HttpResponseException
untuk segera menghentikan pemrosesan. Selain itu untuk kesalahan model dalam tindakan kami, kami akan menyerahkan kamus status model keRequest.CreateErrorResponse
ekstensi dan membungkusnya dengan aHttpResponseException
. Menambahkan kamus model keadaan menghasilkan daftar kesalahan model yang dikirim di badan respons.Untuk kesalahan yang terjadi di lapisan yang lebih tinggi, kesalahan server, kami membiarkan gelembung pengecualian ke aplikasi Web API, di sini kami memiliki filter pengecualian global yang melihat pengecualian, mencatatnya dengan ELMAH dan mencoba memahami pengaturannya pada HTTP yang benar kode status dan pesan kesalahan ramah yang relevan sebagai isi lagi di a
HttpResponseException
. Untuk pengecualian yang tidak kami harapkan klien akan menerima kesalahan server internal 500 default, tetapi pesan umum karena alasan keamanan.Perbarui 3
Baru-baru ini, setelah mengambil Web API 2, untuk mengirim kembali kesalahan umum, kami sekarang menggunakan antarmuka IHttpActionResult , khususnya kelas
System.Web.Http.Results
bawaan di dalam namespace seperti NotFound, BadRequest ketika mereka cocok, jika mereka tidak diperluas, misalnya hasil NotFound dengan pesan respons:sumber
ASP.NET Web API 2 sangat menyederhanakannya. Misalnya, kode berikut:
mengembalikan konten berikut ke browser saat item tidak ditemukan:
Saran: Jangan melempar Kesalahan HTTP 500 kecuali ada kesalahan katastropik (misalnya, Pengecualian Kesalahan WCF). Pilih kode status HTTP yang sesuai yang mewakili keadaan data Anda. (Lihat tautan apigee di bawah ini.)
Tautan:
sumber
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
Apa perbedaan antaraCreateResponse
danCreateErrorResponse
using System.Net.Http;
agarCreateResponse()
metode ekstensi muncul.Sepertinya Anda mengalami lebih banyak masalah dengan Validasi daripada kesalahan / pengecualian, jadi saya akan mengatakan sedikit tentang keduanya.
Validasi
Tindakan pengontrol umumnya harus mengambil Model Input di mana validasi dinyatakan langsung pada model.
Kemudian Anda dapat menggunakan
ActionFilter
yang secara otomatis mengirim pesan validasi kembali ke klien.Untuk informasi lebih lanjut tentang ini, periksa http://ben.onfabrik.com/posts/automatic-modelstate-validation-in-aspnet-mvc
Menangani kesalahan
Yang terbaik adalah mengembalikan pesan kembali ke klien yang mewakili pengecualian yang terjadi (dengan kode status yang relevan).
Di luar kotak Anda harus menggunakan
Request.CreateErrorResponse(HttpStatusCode, message)
jika Anda ingin menentukan pesan. Namun, ini mengikat kode keRequest
objek, yang tidak perlu Anda lakukan.Saya biasanya membuat jenis "aman" pengecualian saya sendiri yang saya harapkan klien akan tahu bagaimana menangani dan membungkus semua orang lain dengan kesalahan 500 generik.
Menggunakan filter tindakan untuk menangani pengecualian akan terlihat seperti ini:
Kemudian Anda dapat mendaftarkannya secara global.
Ini adalah jenis pengecualian khusus saya.
Contoh pengecualian yang dapat saya lemparkan oleh API.
sumber
var exception = context.Exception as WebException;
itu salah ketik, seharusnyaApiException
Anda dapat melempar HttpResponseException
sumber
Untuk Web API 2 metode saya secara konsisten mengembalikan IHttpActionResult jadi saya menggunakan ...
sumber
System.Net.Http
Jika Anda menggunakan ASP.NET Web API 2, cara termudah adalah dengan menggunakan Metode Pendek ApiController. Ini akan menghasilkan BadRequestResult.
sumber
return BadRequest(ModelState);
Anda dapat menggunakan ActionFilter khusus di Web Api untuk memvalidasi model
}
Daftarkan kelas CustomAttribute di webApiConfig.cs config.Filters.Add (DRFValidationFilters baru ());
sumber
Membangun
Manish Jain
jawaban (yang dimaksudkan untuk Web API 2 yang menyederhanakan banyak hal):1) Gunakan struktur validasi untuk merespons sebanyak mungkin kesalahan validasi. Struktur ini juga dapat digunakan untuk menanggapi permintaan yang datang dari formulir.
2) Lapisan layanan akan kembali
ValidationResult
s, terlepas dari operasi yang berhasil atau tidak. Misalnya:3) Pengontrol API akan menyusun respons berdasarkan hasil fungsi layanan
Salah satu opsi adalah menempatkan hampir semua parameter sebagai opsional dan melakukan validasi khusus yang mengembalikan respons yang lebih bermakna. Juga, saya berhati-hati untuk tidak membiarkan pengecualian melampaui batas layanan.
sumber
Gunakan metode "InternalServerError" bawaan (tersedia di ApiController):
sumber
Hanya untuk memperbarui pada kondisi saat ini ASP.NET WebAPI. Antarmuka sekarang dipanggil
IActionResult
dan implementasi tidak banyak berubah:sumber
Untuk kesalahan di mana modelstate.isvalid salah, saya biasanya mengirim kesalahan karena dilemparkan oleh kode. Mudah dimengerti oleh pengembang yang mengonsumsi layanan saya. Saya biasanya mengirim hasilnya menggunakan kode di bawah ini.
Ini mengirimkan kesalahan ke klien dalam format di bawah ini yang pada dasarnya adalah daftar kesalahan:
sumber