Saya menggunakan ASP.NET Core untuk proyek REST API baru saya setelah menggunakan ASP.NET Web API biasa selama bertahun-tahun. Saya tidak melihat cara yang baik untuk menangani pengecualian di ASP.NET Core Web API. Saya mencoba menerapkan pengecualian penanganan filter / atribut:
public class ErrorHandlingFilter : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
HandleExceptionAsync(context);
context.ExceptionHandled = true;
}
private static void HandleExceptionAsync(ExceptionContext context)
{
var exception = context.Exception;
if (exception is MyNotFoundException)
SetExceptionResult(context, exception, HttpStatusCode.NotFound);
else if (exception is MyUnauthorizedException)
SetExceptionResult(context, exception, HttpStatusCode.Unauthorized);
else if (exception is MyException)
SetExceptionResult(context, exception, HttpStatusCode.BadRequest);
else
SetExceptionResult(context, exception, HttpStatusCode.InternalServerError);
}
private static void SetExceptionResult(
ExceptionContext context,
Exception exception,
HttpStatusCode code)
{
context.Result = new JsonResult(new ApiResponse(exception))
{
StatusCode = (int)code
};
}
}
Dan inilah pendaftaran Startup filter saya:
services.AddMvc(options =>
{
options.Filters.Add(new AuthorizationFilter());
options.Filters.Add(new ErrorHandlingFilter());
});
Masalah yang saya alami adalah bahwa ketika pengecualian terjadi pada saya AuthorizationFilter
itu tidak ditangani olehErrorHandlingFilter
. Saya mengharapkan untuk ditangkap di sana seperti itu bekerja dengan ASP.NET Web API lama.
Jadi bagaimana saya bisa menangkap semua pengecualian aplikasi dan juga pengecualian dari Filter Tindakan?
c#
exception
asp.net-core
Andrei
sumber
sumber
UseExceptionHandler
middleware?UseExceptionHandler
middlewareJawaban:
Middleware Handling Pengecualian
Setelah banyak percobaan dengan pendekatan penanganan pengecualian yang berbeda, saya akhirnya menggunakan middleware. Itu berhasil yang terbaik untuk aplikasi ASP.NET Core Web API saya. Ini menangani pengecualian aplikasi serta pengecualian dari filter tindakan dan saya memiliki kontrol penuh atas penanganan pengecualian dan respons HTTP. Ini pengecualian saya menangani middleware:
Daftarkan sebelum MVC di
Startup
kelas:Anda dapat menambahkan jejak stack, nama jenis pengecualian, kode kesalahan atau apa pun yang Anda inginkan. Sangat fleksibel. Berikut adalah contoh tanggapan pengecualian:
Pertimbangkan menyuntikkan
IOptions<MvcJsonOptions>
keInvoke
metode untuk kemudian menggunakannya ketika Anda membuat serial objek respon untuk memanfaatkan pengaturan serialisasi ASP.NET MVCJsonConvert.SerializeObject(errorObj, opts.Value.SerializerSettings)
untuk konsistensi serialisasi yang lebih baik di semua titik akhir.Pendekatan 2
Ada API tidak jelas lainnya yang disebut
UseExceptionHandler
"ok" untuk skenario sederhana:Ini bukan cara yang sangat jelas tapi mudah untuk mengatur penanganan pengecualian. Namun saya masih lebih suka pendekatan middleware daripada itu karena saya mendapatkan lebih banyak kontrol dengan kemampuan untuk menyuntikkan dependensi yang diperlukan.
sumber
app.UseMiddleware<ErrorHandlingMiddleware>();
ke sebelumapp.UseStaticFiles();
. Pengecualian tampaknya ditangkap dengan benar sekarang. Ini membuat saya percaya bahwaapp.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); app.UseBrowserLink();
lakukan beberapa peretasan middleware sihir internal untuk mendapatkan pemesanan middleware yang benar.Terbaru
Asp.Net Core
(setidaknya dari 2.2, mungkin sebelumnya) memiliki middleware built-in yang membuatnya sedikit lebih mudah dibandingkan dengan implementasi dalam jawaban yang diterima:Seharusnya melakukan hampir sama, hanya sedikit kode untuk menulis.
Penting: Ingatlah untuk menambahkannya sebelumnya
UseMvc
(atauUseRouting
dalam .Net Core 3) karena urutannya penting.sumber
Taruhan terbaik Anda adalah menggunakan middleware untuk mencapai pencatatan yang Anda cari. Anda ingin menempatkan pengecualian masuk dalam satu middleware dan kemudian menangani halaman kesalahan yang ditampilkan kepada pengguna di middleware yang berbeda. Itu memungkinkan pemisahan logika dan mengikuti desain yang telah disusun Microsoft dengan 2 komponen middleware. Berikut ini tautan yang bagus ke dokumentasi Microsoft: Penanganan Kesalahan di ASP.Net Core
Untuk contoh spesifik Anda, Anda mungkin ingin menggunakan salah satu ekstensi di middleware StatusCodePage atau roll sendiri seperti ini .
Anda dapat menemukan contoh di sini untuk mencatat pengecualian: ExceptionHandlerMiddleware.cs
Jika Anda tidak menyukai implementasi spesifik tersebut, maka Anda juga dapat menggunakan ELM Middleware , dan berikut adalah beberapa contohnya: Elm Exception Middleware
Jika itu tidak berhasil untuk kebutuhan Anda, Anda selalu dapat menggulung komponen Middleware Anda sendiri dengan melihat implementasi ExceptionHandlerMiddleware dan ElmMiddleware untuk memahami konsep untuk membangun sendiri.
Sangat penting untuk menambahkan pengecualian penanganan middleware di bawah middleware StatusCodePages tetapi di atas semua komponen middleware lainnya. Dengan begitu middleware Pengecualian Anda akan menangkap pengecualian, catat, lalu izinkan permintaan untuk melanjutkan ke middleware StatusCodePage yang akan menampilkan halaman kesalahan ramah kepada pengguna.
sumber
UseStatusCodePages
itu berguna dalam implementasi layanan Web API. Tidak ada tampilan atau HTML sama sekali, hanya tanggapan JSON ...Jawaban yang diterima dengan baik banyak membantu saya tetapi saya ingin melewatkan HttpStatusCode di middleware saya untuk mengelola kode status kesalahan saat runtime.
Menurut tautan ini saya mendapat ide untuk melakukan hal yang sama. Jadi saya menggabungkan Jawaban Andrei dengan ini. Jadi kode terakhir saya di bawah ini:
1. Kelas dasar
2. Jenis Kelas Pengecualian Kustom
3. Perkecualian Perkecualian Kustom
4. Metode Perpanjangan
5. Konfigurasikan Metode di startup.cs
Sekarang metode login saya di pengontrol Akun:
Di atas Anda dapat melihat apakah saya belum menemukan pengguna kemudian menaikkan HttpStatusCodeException di mana saya telah melewati HttpStatusCode.NotFound status dan pesan khusus di
middleware
Diblokir akan dipanggil yang akan melewati kontrol
.
Tetapi bagaimana jika saya mendapat kesalahan runtime sebelumnya? Untuk itu saya telah menggunakan try catch block yang melempar exception dan akan ditangkap di catch (Exception exceptionObj) block dan akan melewati kontrol ke
metode.
Saya telah menggunakan kelas ErrorDetails tunggal untuk keseragaman.
sumber
startup.cs
dalamvoid Configure(IapplicationBuilder app)
saya mendapatkan kesalahanIApplicationBuilder does not contain a definition for ConfigureCustomExceptionMiddleware
. Dan saya menambahkan referensi, dimanaCustomExceptionMiddleware.cs
.Untuk Mengkonfigurasi perilaku penanganan pengecualian per jenis pengecualian, Anda dapat menggunakan Middleware dari paket NuGet:
ASP.NET Core 2.0
ASP.NET Core 2.1+
.Contoh kode:
sumber
Pertama, terima kasih kepada Andrei karena saya mendasarkan solusi saya pada contohnya.
Saya termasuk milik saya karena sampel yang lebih lengkap dan mungkin menghemat waktu pembaca.
Keterbatasan pendekatan Andrei adalah bahwa tidak menangani pencatatan, menangkap variabel permintaan yang berpotensi bermanfaat dan negosiasi konten (itu akan selalu mengembalikan JSON tidak peduli apa yang klien minta - XML / teks biasa, dll).
Pendekatan saya adalah menggunakan ObjectResult yang memungkinkan kita untuk menggunakan fungsi yang dipanggang ke dalam MVC.
Kode ini juga mencegah caching dari respons.
Respons kesalahan telah didekorasi sedemikian rupa sehingga dapat diserialisasi oleh serializer XML.
sumber
Pertama, konfigurasikan ASP.NET Core 2
Startup
untuk menjalankan kembali ke halaman kesalahan untuk setiap kesalahan dari server web dan setiap pengecualian yang tidak ditangani.Selanjutnya, tentukan jenis pengecualian yang akan memungkinkan Anda membuang kesalahan dengan kode status HTTP.
Terakhir, di pengontrol Anda untuk halaman kesalahan, sesuaikan respons berdasarkan alasan kesalahan dan apakah respons akan dilihat langsung oleh pengguna akhir. Kode ini mengasumsikan semua URL API dimulai dengan
/api/
.ASP.NET Core akan mencatat rincian kesalahan untuk Anda debug, jadi kode status mungkin yang Anda inginkan untuk meminta (mungkin tidak dipercaya) pemohon. Jika Anda ingin menampilkan lebih banyak info, Anda dapat meningkatkan
HttpException
untuk memberikannya. Untuk kesalahan API, Anda bisa memasukkan info kesalahan yang dikodekan JSON di badan pesan dengan menggantinyareturn StatusCode...
denganreturn Json...
.sumber
gunakan middleware atau IExceptionHandlerPathFeature baik-baik saja. ada cara lain di eshop
buat filter pengecualian dan daftarkan
sumber