IIS7 Mengganti customErrors saat mengatur Response.StatusCode?

98

Ada masalah aneh di sini. Semua orang tahu bahwa jika Anda menggunakan customErrorsbagian web.config untuk membuat halaman kesalahan kustom, Anda harus mengaturnya Response.StatusCodeke apa pun yang sesuai. Misalnya, jika saya membuat halaman 404 tersuai dan menamainya 404.aspx, saya dapat memasukkan <% Response.StatusCode = 404 %>isinya untuk membuatnya memiliki tajuk status 404 yang sebenarnya.

Ikuti saya sejauh ini? Baik. Sekarang coba lakukan ini di IIS7. Saya tidak bisa membuatnya bekerja, titik. Jika Response.StatusCodediatur di halaman kesalahan kustom, IIS7 tampaknya menimpa halaman kesalahan kustom sepenuhnya, dan menampilkan halaman statusnya sendiri (jika Anda memiliki yang dikonfigurasi.)

Apakah ada orang lain yang melihat perilaku ini dan mungkin juga tahu cara mengatasinya? Itu bekerja di bawah IIS6, jadi saya tidak tahu mengapa banyak hal berubah.

Catatan: Ini tidak sama dengan masalah di ASP.NET Custom 404 Returning 200 OK Alih-alih 404 Not Found

Nicholas
sumber
Saya memiliki pertanyaan yang sama. Sudah dijawab di sini http://stackoverflow.com/questions/347281/asp-net-custom-404-returning-200-ok-instead-of-404-not-found .
Bobby Cannon
Bobby, saya benar-benar menemukan pertanyaan itu dan mencobanya, tetapi itu tidak menyelesaikan masalah. Tapi terima kasih.
Nicholas
Saya ingin mengomentari bahwa masalah ini juga terjadi saat beralih dari pipa Klasik ke Terpadu. Saya menggunakan solusi @PavelChuchuva (solusi @RickStrahl juga berfungsi). Saya menduga "passthrough" di Klasik adalah otomatis, di Terpadu dibutuhkan penanganan halaman kesalahan global server ..
sonjz

Jawaban:

116

Tetapkan existingResponse ke PassThrough di bagian system.webServer / httpErrors:

  <system.webServer>
    <httpErrors existingResponse="PassThrough" />
  </system.webServer>

Nilai default dari properti existingResponse adalah Otomatis:

Otomatis memberi tahu modul kesalahan khusus untuk melakukan hal yang benar . Teks kesalahan sebenarnya yang dilihat oleh klien akan terpengaruh, bergantung pada nilai fTrySkipCustomErrors yang dikembalikan saat IHttpResponse::GetStatuspanggilan. Jika fTrySkipCustomErrors disetel ke true, modul kesalahan khusus akan membiarkan respons lewat, tetapi jika disetel ke false, modul kesalahan khusus menggantikan teks dengan teksnya sendiri.

Informasi selengkapnya: Apa yang diharapkan dari modul kesalahan kustom IIS7

Pavel Chuchuva
sumber
3
Perhatikan bahwa menyetel existingResponse ke PassThrough dapat menyebabkan beberapa efek samping. Harap kuasai tautan yang disediakan oleh Pavel sebelum ada perubahan.
Lex Li
Apakah <httpErrors existingResponse="PassThrough" />setara dengan Response.TrySkipIisCustomErrorsatau apakah mereka berperilaku berbeda?
Asbjørn Ulsberg
1
@sbjornu Mereka mencapai hal yang sama tetapi dengan Response.TrySkipIisCustomErrorsAnda mendapatkan kontrol yang lebih baik saat menampilkan kesalahan kustom IIS.
Pavel Chuchuva
terima kasih, saya telah melihat banyak info tentang response.tryskipiiscustomerrors tetapi tidak banyak tentang respons yang ada.
HBCondo
Saya memecahkan masalah dengan halaman kesalahan kustom yang tidak berfungsi pada host web saya yang menjalankan IIS7 hanya dengan menyetel existingResponse = "Auto", yang sangat mengejutkan karena artikel mereferensikan klaim yang merupakan default. Jelas bukan ... atau perusahaan hosting saya menetapkan default yang salah di tempat lain, saya kira. Bagaimanapun saya berharap itu menyelamatkan seseorang dari beberapa jam: \
Eric Sassaman
80

Cara termudah untuk membuat perilaku konsisten adalah dengan menghapus kesalahan dan menggunakan Response.TrySkipIisCustomErrors dan menyetelnya ke true. Ini akan menimpa penanganan halaman kesalahan global IIS dari dalam halaman Anda atau penangan kesalahan global di Application_Error.

Server.ClearError();
Response.TrySkipIisCustomErrors = true;

Biasanya Anda harus melakukan ini di penangan Application_Error Anda yang menangani semua kesalahan yang tidak ditangkap oleh penangan kesalahan aplikasi Anda.

Info lebih rinci dapat ditemukan di posting blog ini: http://www.west-wind.com/weblog/posts/745738.aspx

Rick Strahl
sumber
2
Ini juga tidak berfungsi untuk saya (IIS8), dan sarannya tampaknya tidak cocok dengan OP (dengan asumsi saya membacanya dengan benar). Saya ingin yang customErrordikonfigurasi dalam Web.config untuk memicu. Dengan Response.TrySkipIisCustomErrors = trueSaya mendapatkan perilaku yang sama: Halaman kesalahan jelek yang dihasilkan server ditampilkan. Dengan itu diatur ke falsetidak ada yang terjadi - jendela browser kosong.
Shawn South
Bekerja dengan baik untuk saya! Meskipun pengaturan yang disebutkan Pavel Chuchuva dalam jawabannya juga berfungsi, ada beberapa efek samping yang menyebabkan masalah lain. Pengaturan ini membiarkan saya melewati kesalahan IIS menimpa skenario tertentu yang saya inginkan, sementara membiarkan perilaku utuh untuk yang lainnya.
Kevin Tighe
Bekerja dengan baik di Azure untuk saya. Header serverServer:Microsoft-IIS/8.5 X-AspNet-Version:4.0.30319 X-AspNetMvc-Version:5.2 X-Powered-By:ASP.NET
oxfn
Saya masih merasa saya harus mengatur customErrors mode="Off"agar ini berfungsi. Jika saya melakukannya, maka httpErrors existingResponse = "Auto" (default) berfungsi dengan baik untuk saya ketika saya menggunakan kode dalam jawaban ini.
AaronLS
11

Dipecahkan: Ternyata "Kesalahan Terperinci" perlu diaktifkan agar IIS7 "melewati" halaman kesalahan yang mungkin Anda miliki. Lihat http://forums.iis.net/t/1146653.aspx

Nicholas
sumber
1
Meskipun yang ini ditandai sebagai jawaban, saya pikir ada baiknya membaca balasan lain untuk mendapatkan lebih banyak wawasan tentang topik tersebut.
Lex Li
Juga bisa bagus untuk dihapus. HandleErrorAttribute di FilterConfig
Per G
4

Saya tidak yakin apakah ini serupa atau tidak, tetapi saya memecahkan masalah yang terdengar serupa di permukaan dan inilah cara saya menanganinya.

Pertama-tama, nilai default untuk existingResponse (Auto) adalah jawaban yang benar dalam kasus saya, karena saya memiliki 404, 400, dan 500 kustom (saya dapat membuat yang lain, tetapi ketiganya sudah cukup untuk apa yang saya lakukan). Berikut adalah bagian relevan yang membantu saya.

Dari web.config:

<customErrors mode="Off" />

Dan

<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
  <clear />
  <error statusCode="404" path="/errors/404.aspx" responseMode="ExecuteURL" />
  <error statusCode="500" path="/errors/500.aspx" responseMode="ExecuteURL" />
  <error statusCode="400" path="/errors/400.aspx" responseMode="ExecuteURL" />
</httpErrors>

Dari sana, saya menambahkan ini ke Application_Error di global.asax:

    Response.TrySkipIisCustomErrors = True

Pada setiap halaman kesalahan kustom saya, saya harus menyertakan kode status respons yang benar. Dalam kasus saya, saya menggunakan 404 tersuai untuk mengirim pengguna ke bagian berbeda dari situs saya, jadi saya tidak ingin kode status 404 dikembalikan kecuali itu sebenarnya adalah laman mati.

Bagaimanapun, begitulah cara saya melakukannya. Harapan yang membantu seseorang.

SEFL
sumber
3

Masalah ini sangat memusingkan. Tidak ada saran yang disebutkan sebelumnya yang menyelesaikannya untuk saya, jadi saya menyertakan solusi saya. Sebagai catatan, lingkungan / platform kami menggunakan:

  • .NET Framework 4
  • MVC 3
  • IIS8 (workstation) dan IIS7 (server web)

Secara khusus, saya mencoba mendapatkan respons HTTP 404 yang akan mengarahkan pengguna ke halaman 404 tersuai kami (melalui pengaturan Web.config).

Pertama, kode saya harus membuang HttpException. Mengembalikan a NotFoundResultdari pengontrol tidak mencapai hasil yang saya cari.

throw new HttpException(404, "There is no class with that subject");

Lalu aku harus mengkonfigurasi kedua yang customErrorsdan httpErrornode di web.config.

<customErrors mode="On" defaultRedirect="/classes/Error.aspx">
  <error statusCode="404" redirect="/classes/404.html" />
</customErrors>

...

<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
  <clear />
  <error statusCode="404" path="/classes/404.aspx" responseMode="ExecuteURL" />
</httpErrors>

Perhatikan bahwa saya meninggalkan existingResponseas Auto, yang berbeda dari solusi yang disediakan @sefl.

The customErrorspengaturan tampaknya diperlukan untuk menangani saya secara eksplisit dilemparkan HttpException, sedangkan httpErrorssimpul ditangani URL yang jatuh di luar pola rute yang ditentukan dalam Globals.asax.cs.

PS Dengan pengaturan ini saya tidak perlu mengatur Response.TrySkipIisCustomErrors

Shawn South
sumber
2

TrySkipIisCustomErrorshanyalah bagian dari teka-teki. Jika Anda menggunakan Halaman Kesalahan Khusus tetapi Anda juga ingin mengirimkan beberapa konten RESTful berdasarkan status 4xx, maka Anda mengalami masalah. Menyetel httpErrors.existingResponse web.config ke "Otomatis" tidak berfungsi, karena .net tampaknya selalu mengirimkan beberapa konten halaman ke IIS, oleh karena itu menggunakan "Otomatis" menyebabkan semua (atau setidaknya beberapa) Halaman Kesalahan Kustom tidak digunakan. Menggunakan "Ganti" juga tidak akan berfungsi, karena tanggapan akan berisi kode status http Anda, tetapi isinya akan kosong atau diisi dengan Halaman Kesalahan Khusus. Dan "PassThrough" ternyata mematikan CEP, sehingga tidak bisa digunakan.

Jadi jika Anda ingin melewati CEP untuk beberapa kasus (dengan melewati maksud saya mengembalikan status 4xx dengan beberapa konten) Anda akan memerlukan langkah tambahan: bersihkan kesalahan:

void Application_Error(object sender, EventArgs e)
{
    var httpException = Context.Server.GetLastError() as HttpException;
    var statusCode = httpException != null ? httpException.GetHttpCode() : (int)HttpStatusCode.InternalServerError;

    Context.Server.ClearError();
    Context.Response.StatusCode = statusCode;
}

Jadi jika Anda ingin menggunakan respons REST (mis. 400 - Permintaan Buruk) dan mengirim beberapa konten dengannya, Anda hanya perlu menyetel TrySkipIisCustomErrorssuatu tempat dalam tindakan dan menyetel existingResponseke "Otomatis" di bagian httpErrors di web.config. Sekarang:

  • ketika tidak ada kesalahan (tindakan mengembalikan 4xx atau 5xx) dan beberapa konten dikembalikan CEP tidak digunakan dan konten diteruskan ke klien;
  • ketika ada kesalahan (pengecualian dilemparkan) konten yang dikembalikan oleh penangan kesalahan dihapus, sehingga CEP digunakan.

Jika Anda ingin mengembalikan status dengan konten kosong dari tindakan Anda, tindakan itu akan diperlakukan sebagai respons kosong dan CEP akan ditampilkan, jadi ada ruang untuk meningkatkan kode ini.

Łukasƨ Fronczyk
sumber
0

Secara default IIS 7 menggunakan pesan kesalahan kustom rinci jadi saya akan berasumsi bahwa Response.StatusCode akan sama dengan 404.XX daripada hanya 404.

Anda dapat mengkonfigurasi IIS7 untuk menggunakan kode pesan kesalahan yang lebih sederhana atau mengubah kode Anda menangani pesan kesalahan yang lebih rinci yang ditawarkan IIS7.

Info lebih lanjut tersedia di sini: http://blogs.iis.net/rakkimk/archive/2008/10/03/iis7-enabling-custom-error-pages.aspx

Penyelidikan lebih lanjut mengungkapkan bahwa saya salah jalan - pesan rinci tidak secara default tetapi mungkin mereka telah diaktifkan, di kotak Anda jika Anda melihat pesan kesalahan berbeda yang Anda sebutkan.

batal demi hukum
sumber
Response.StatusCode adalah bilangan bulat, jadi saya tidak melihat cara untuk menyetel kode yang lebih spesifik daripada hanya "404". Saya telah mengonfigurasi IIS7 untuk menggunakan / menampilkan halaman kesalahan kustom, seperti yang ditunjukkan URL Anda.
Nicholas
Hmmm ... Sayangnya saya tidak dapat menguji saat ini karena saya tidak menggunakan komputer rumah saya. Jika Anda tidak memiliki solusi saat itu - saya akan melihatnya malam ini.
batal demi hukum