PEMBARUAN
Karena jawaban ini memang memberikan solusi, saya tidak akan mengeditnya, tetapi saya telah menemukan cara yang jauh lebih bersih untuk memecahkan masalah ini. Lihat jawaban saya yang lain untuk detailnya ...
Jawaban Asli:
Saya tahu mengapa Application_Error()
metode ini tidak dipanggil ...
Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute()); // this line is the culprit
}
...
}
Secara default (saat proyek baru dibuat), aplikasi MVC memiliki beberapa logika di Global.asax.cs
file. Logika ini digunakan untuk memetakan rute dan mendaftarkan filter. Secara default, ini hanya mendaftarkan satu filter: HandleErrorAttribute
filter. Saat customErrors aktif (atau melalui permintaan jarak jauh saat disetel ke RemoteOnly), HandleErrorAttribute memberi tahu MVC untuk mencari tampilan Error dan tidak pernah memanggil Application_Error()
metode tersebut. Saya tidak dapat menemukan dokumentasi ini tetapi dijelaskan dalam jawaban ini di programmers.stackexchange.com .
Untuk mendapatkan metode ApplicationError () yang dipanggil untuk setiap pengecualian yang tidak tertangani, cukup hapus baris yang mendaftarkan filter HandleErrorAttribute.
Sekarang masalahnya adalah: Bagaimana cara mengkonfigurasi customErrors untuk mendapatkan apa yang Anda inginkan ...
Secara default, bagian customErrors redirectMode="ResponseRedirect"
. Anda juga dapat menentukan atribut defaultRedirect sebagai rute MVC. Saya membuat ErrorController yang sangat sederhana dan mengubah web.config saya agar terlihat seperti ini ...
web.config
<customErrors mode="RemoteOnly" redirectMode="ResponseRedirect" defaultRedirect="~/Error">
<error statusCode="404" redirect="~/Error/PageNotFound" />
</customErrors>
Masalah dengan solusi ini adalah bahwa ia 302 mengalihkan ke URL kesalahan Anda dan kemudian laman tersebut merespons dengan kode status 200. Hal ini menyebabkan Google mengindeks halaman kesalahan yang buruk. Ini juga tidak terlalu sesuai dengan spesifikasi HTTP. Yang ingin saya lakukan adalah tidak mengalihkan, dan menimpa tanggapan asli dengan tampilan kesalahan khusus saya.
Saya mencoba untuk berubah redirectMode="ResponseRewrite"
. Sayangnya, opsi ini tidak mendukung rute MVC , hanya halaman HTML statis atau ASPX. Saya mencoba menggunakan halaman HTML statis pada awalnya tetapi kode respons masih 200 tetapi, setidaknya itu tidak mengarahkan. Saya kemudian mendapat ide dari jawaban ini ...
Saya memutuskan untuk menyerah pada MVC karena penanganan kesalahan. Saya membuat Error.aspx
dan a PageNotFound.aspx
. Halaman-halaman ini sangat sederhana tetapi memiliki satu keajaiban ...
<script type="text/C#" runat="server">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Response.StatusCode = (int) System.Net.HttpStatusCode.InternalServerError;
}
</script>
Blok ini memberi tahu halaman yang akan disajikan dengan kode status yang benar. Secara kasar, pada halaman PageNotFound.aspx, saya menggunakan HttpStatusCode.NotFound
sebagai gantinya. Saya mengubah web.config saya agar terlihat seperti ini ...
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx">
<error statusCode="404" redirect="~/PageNotFound.aspx" />
</customErrors>
Semuanya bekerja dengan sempurna!
Ringkasan:
- Hapus garis:
filters.Add(new HandleErrorAttribute());
- Gunakan
Application_Error()
metode untuk mencatat pengecualian
- Gunakan customErrors dengan ResponseRewrite, yang mengarah ke halaman ASPX
- Buat halaman ASPX bertanggung jawab atas kode status responsnya sendiri
Ada beberapa kelemahan yang saya perhatikan dengan solusi ini.
- Halaman ASPX tidak dapat membagikan markup apa pun dengan template Razor, saya harus menulis ulang markup header dan footer standar situs web kami untuk tampilan dan nuansa yang konsisten.
- Halaman * .aspx dapat diakses secara langsung dengan menekan URL-nya
Ada solusi untuk masalah ini tetapi saya tidak cukup khawatir dengan mereka untuk melakukan pekerjaan tambahan.
Saya harap ini membantu semua orang!