IIS7 Ghi đè các lỗi customErrors khi đặt Mã phản hồi trạng thái?


98

Có một vấn đề kỳ lạ ở đây. Mọi người đều biết rằng nếu bạn sử dụng customErrorsphần của web.config để tạo trang lỗi tùy chỉnh, bạn nên đặt của mình Response.StatusCodethành bất kỳ điều gì phù hợp. Ví dụ: nếu tôi tạo một trang 404 tùy chỉnh và đặt tên là 404.aspx, tôi có thể đưa <% Response.StatusCode = 404 %>nội dung vào để làm cho nó có tiêu đề trạng thái 404 đúng.

Theo tôi cho đến nay? Tốt. Bây giờ hãy thử làm điều này trên IIS7. Tôi không thể làm cho nó hoạt động, thời gian. Nếu Response.StatusCodeđược đặt trong trang lỗi tùy chỉnh, IIS7 dường như sẽ ghi đè hoàn toàn trang lỗi tùy chỉnh và hiển thị trang trạng thái của chính nó (nếu bạn đã định cấu hình một trang).

Có ai khác đã thấy hành vi này và cũng có thể biết cách giải quyết nó không? Nó đang hoạt động theo IIS6, vì vậy tôi không biết tại sao mọi thứ lại thay đổi.

Lưu ý: Điều này không giống với vấn đề trong ASP.NET Custom 404 Trả lại 200 OK Thay vì 404 Không tìm thấy


Tôi đã có cùng một câu hỏi. Đã được trả lời ở đây http://stackoverflow.com/questions/347281/asp-net-custom-404-returning-200-ok-instead-of-404-not-found .
Bobby Cannon

Bobby, tôi thực sự đã tìm thấy câu hỏi đó và thử nó, nhưng nó không giải quyết được vấn đề. Nhưng cảm ơn.
Nicholas

Tôi muốn nhận xét rằng vấn đề này cũng xảy ra khi chuyển từ pipeine cổ điển sang tích hợp. Tôi đã sử dụng giải pháp @PavelChuchuva (giải pháp @RickStrahl cũng hoạt động). Tôi đoán là "passthrough" trong Classic là tự động, trong tích hợp nó cần xử lý trang lỗi toàn cầu của máy chủ ..
sonjz

Câu trả lời:


116

Đặt hiện tạiResponse thành PassThrough trong phần system.webServer / httpErrors:

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

Giá trị mặc định của thuộc tính currentResponse là Auto:

Tự động nói với mô-đun lỗi tùy chỉnh để làm điều đúng . Văn bản lỗi thực tế mà khách hàng nhìn thấy sẽ bị ảnh hưởng tùy thuộc vào giá trị của fTrySkipCustomErrors được trả về trong IHttpResponse::GetStatuscuộc gọi. Khi fTrySkipCustomErrors được đặt thành true, mô-đun lỗi tùy chỉnh sẽ cho phép phản hồi đi qua nhưng nếu nó được đặt thành false, mô-đun lỗi tùy chỉnh sẽ thay thế văn bản bằng văn bản của chính nó.

Thông tin thêm: Điều gì sẽ xảy ra từ mô-đun lỗi tùy chỉnh IIS7


3
Lưu ý rằng việc đặt hiện tạiResponse thành PassThrough có thể dẫn đến một số tác dụng phụ. Vui lòng nắm vững liên kết do Pavel cung cấp trước khi có bất kỳ thay đổi nào.
Lex Li

<httpErrors existingResponse="PassThrough" />tương đương với Response.TrySkipIisCustomErrorshay họ hành xử khác nhau?
Asbjørn Ulsberg

1
@sbjornu Họ đạt được điều tương tự nhưng với việc Response.TrySkipIisCustomErrorsbạn kiểm soát tốt hơn thời điểm hiển thị lỗi tùy chỉnh IIS.
Pavel Chuchuva

cảm ơn bạn, tôi đã xem rất nhiều thông tin về response.tryskipiiscustomerrors nhưng không nhiều về hiệnresponse.
HBCondo

Tôi đã giải quyết sự cố với các trang lỗi tùy chỉnh không hoạt động trên máy chủ lưu trữ web đang chạy IIS7 của tôi chỉ đơn giản bằng cách đặt currentResponse = "Auto", điều này rất đáng ngạc nhiên vì bài báo đề cập đến tuyên bố đó là mặc định. Rõ ràng là không phải ... hoặc công ty lưu trữ của tôi đã đặt sai mặc định ở nơi khác, tôi cho là vậy. Dù bằng cách nào, tôi hy vọng điều đó sẽ cứu ai đó trong vài giờ: \
Eric Sassaman,

80

Cách dễ nhất để làm cho hành vi nhất quán là xóa lỗi và sử dụng Response.TrySkipIisCustomErrors và đặt nó thành true. Điều này sẽ ghi đè xử lý trang lỗi toàn cầu IIS từ bên trong trang của bạn hoặc trình xử lý lỗi chung trong Application_Error.

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

Thông thường, bạn nên làm điều này trong trình xử lý Application_Error để xử lý tất cả các lỗi mà trình xử lý lỗi ứng dụng của bạn không bắt được.

Thông tin chi tiết hơn có thể được tìm thấy trong bài đăng trên blog này: http://www.west-wind.com/weblog/posts/745738.aspx


2
Điều này cũng không hiệu quả với tôi (IIS8) và lời khuyên dường như không phù hợp với OP (giả sử tôi đang đọc nó chính xác). Tôi muốn các customErrorcấu hình trong Web.config để kích hoạt. Với Response.TrySkipIisCustomErrors = truetôi nhận được cùng một hành vi: Trang lỗi xấu xí do máy chủ tạo được hiển thị. Khi nó được đặt thành falsekhông có gì xảy ra - một cửa sổ trình duyệt trống.
Shawn South

Làm việc tốt cho tôi! Mặc dù cài đặt mà Pavel Chuchuva đề cập trong câu trả lời của mình cũng hoạt động, nó có một số tác dụng phụ gây ra các vấn đề khác. Cài đặt này cho phép tôi bỏ qua ghi đè lỗi IIS trong trường hợp cụ thể mà tôi muốn, trong khi vẫn giữ nguyên hành vi cho mọi thứ khác.
Kevin Tighe

Làm việc tốt trong Azure đối với tôi. Tiêu đề máy chủServer:Microsoft-IIS/8.5 X-AspNet-Version:4.0.30319 X-AspNetMvc-Version:5.2 X-Powered-By:ASP.NET
oxfn

Tôi vẫn thấy tôi cần phải thiết lập customErrors mode="Off"để điều này hoạt động. Nếu tôi làm điều đó, thì httpErrors beingResponse = "Auto" (mặc định) sẽ hoạt động tốt cho tôi khi tôi sử dụng mã trong câu trả lời này.
AaronLS

11

Đã giải quyết: Hóa ra là "Lỗi chi tiết" cần được bật để IIS7 "chuyển" bất kỳ trang lỗi nào bạn có thể mắc phải. Xem http://forums.iis.net/t/1146653.aspx


1
Mặc dù câu trả lời này đã được đánh dấu là câu trả lời, tôi nghĩ rằng rất đáng để đọc các câu trả lời khác để có thêm hiểu biết về chủ đề này.
Lex Li

Ngoài ra, nó có thể là tốt để loại bỏ. HandleErrorAttribute in FilterConfig
Per G

4

Tôi không chắc liệu điều này có tương tự về bản chất hay không, nhưng tôi đã giải quyết một vấn đề nghe có vẻ tương tự trên bề mặt và đây là cách tôi xử lý nó.

Trước hết, giá trị mặc định cho currentResponse (Tự động) là câu trả lời chính xác trong trường hợp của tôi, vì tôi có 404, 400 và 500 tùy chỉnh (tôi có thể tạo những cái khác, nhưng ba cái này sẽ đủ cho những gì tôi đang làm). Đây là các phần có liên quan đã giúp tôi.

Từ web.config:

<customErrors mode="Off" />

<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>

Từ đó, tôi đã thêm điều này vào Application_Error trên global.asax:

    Response.TrySkipIisCustomErrors = True

Trên mỗi trang lỗi tùy chỉnh của tôi, tôi phải bao gồm mã trạng thái phản hồi chính xác. Trong trường hợp của tôi, tôi đang sử dụng 404 tùy chỉnh để đưa người dùng đến các phần khác nhau trên trang web của mình, vì vậy tôi không muốn trả về mã trạng thái 404 trừ khi nó thực sự là một trang đã chết.

Dù sao thì, đó là cách tôi đã làm. Hy vọng rằng sẽ giúp một ai đó.


3

Vấn đề này đã là một vấn đề lớn. Không có đề xuất nào được đề cập trước đây một mình giải quyết được vấn đề đó cho tôi, vì vậy tôi bao gồm cả giải pháp của mình. Đối với hồ sơ, môi trường / nền tảng của chúng tôi sử dụng:

  • .Khung lưới 4
  • MVC 3
  • IIS8 (máy trạm) và IIS7 (máy chủ web)

Cụ thể, tôi đang cố gắng nhận phản hồi HTTP 404 sẽ chuyển hướng người dùng đến trang 404 tùy chỉnh của chúng tôi (thông qua cài đặt Web.config).

Đầu tiên, mã của tôi phải ném một HttpException. Trả lại một NotFoundResulttừ bộ điều khiển không đạt được kết quả như tôi mong đợi.

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

Sau đó, tôi đã phải configure cả các customErrorshttpErrorcác nút trong 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>

Lưu ý rằng tôi đã để nguyên existingResponseAuto, khác với giải pháp mà @sefl cung cấp.

Các customErrorscài đặt dường như là cần thiết để xử lý việc ném rõ ràng của tôi HttpException, trong khi httpErrorsnút xử lý các URL nằm ngoài các mẫu tuyến được chỉ định trong Globals.asax.cs.

PS Với các cài đặt này, tôi không cần thiết lập Response.TrySkipIisCustomErrors


2

TrySkipIisCustomErrorschỉ là một phần của câu đố. Nếu bạn sử dụng Trang lỗi tùy chỉnh nhưng bạn cũng muốn cung cấp một số nội dung RESTful dựa trên trạng thái 4xx thì bạn gặp sự cố. Đặt httpErrors.existingResponse của web.config thành "Tự động" không hoạt động, vì .net dường như luôn phân phối một số nội dung trang đến IIS, do đó, việc sử dụng "Tự động" sẽ khiến tất cả (hoặc ít nhất một số) Trang Lỗi Tùy chỉnh không được sử dụng. Việc sử dụng "Thay thế" cũng sẽ không hoạt động vì phản hồi sẽ chứa mã trạng thái http của bạn, nhưng nội dung của nó sẽ trống hoặc chứa đầy Trang lỗi tùy chỉnh. Và "PassThrough" trên thực tế đã tắt CEP, vì vậy nó không thể được sử dụng.

Vì vậy, nếu bạn muốn bỏ qua CEP trong một số trường hợp (bỏ qua, ý tôi là trả lại trạng thái 4xx với một số nội dung), bạn sẽ cần bước bổ sung: xóa lỗi:

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;
}

Vì vậy, nếu bạn muốn sử dụng phản hồi REST (tức là 400 - Yêu cầu không hợp lệ) và gửi một số nội dung với nó, bạn sẽ chỉ cần đặt TrySkipIisCustomErrorsmột nơi nào đó đang hoạt động và đặt existingResponsethành "Tự động" trong phần httpErrors trong web.config. Hiện nay:

  • khi không có lỗi (action trả về 4xx hoặc 5xx) và một số nội dung được trả về thì CEP không được sử dụng và nội dung được chuyển cho client;
  • khi có lỗi (một ngoại lệ được đưa ra), nội dung do trình xử lý lỗi trả về sẽ bị xóa, vì vậy CEP được sử dụng.

Nếu bạn muốn trả lại trạng thái với nội dung trống từ hành động của bạn, nó sẽ được coi là phản hồi trống và CEP sẽ được hiển thị, vì vậy có một số chỗ để cải thiện mã này.


0

Theo mặc định, IIS 7 sử dụng các thông báo lỗi tùy chỉnh chi tiết, vì vậy tôi giả sử rằng Mã phản hồi sẽ bằng 404.XX thay vì chỉ 404.

Bạn có thể cấu hình IIS7 để sử dụng các mã thông báo lỗi đơn giản hơn hoặc sửa đổi mã của bạn để xử lý các thông báo lỗi chi tiết hơn mà IIS7 đưa ra.

Có thêm thông tin tại đây: http://blogs.iis.net/rakkimk/archive/2008/10/03/iis7-enabling-custom-error-pages.aspx

Điều tra thêm cho thấy tôi đã làm sai cách - các thông báo chi tiết không phải theo mặc định nhưng có lẽ chúng đã được bật, trên hộp của bạn nếu bạn thấy các thông báo lỗi khác nhau mà bạn đã đề cập.


Response.StatusCode là một số nguyên, vì vậy tôi không thấy cách đặt mã cụ thể hơn chỉ là "404". Tôi đã định cấu hình IIS7 để sử dụng / hiển thị các trang lỗi tùy chỉnh, như URL của bạn chỉ ra.
Nicholas

Rất tiếc ... Rất tiếc, tôi không thể kiểm tra vào lúc này vì tôi không sử dụng máy tính tại nhà của mình. Nếu bạn không có giải pháp vào lúc đó - tôi sẽ xem xét tối nay.
nullnvoid
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.