Po próbie skonfigurowania mojej witryny pod kątem Narzędzi Google dla webmasterów stwierdziłem, że moja niestandardowa strona ASP.NET 404 nie zwraca kodu stanu 404. Wyświetlił właściwą stronę niestandardową i poinformował przeglądarkę, że wszystko jest w porządku. Jest to uważane za pozorny błąd 404 lub fałszywy 404. Google tego nie lubi. Znalazłem więc wiele artykułów na ten temat, ale rozwiązanie, którego szukałem, nie działało.
Rozwiązanie, nad którym chcę pracować, polega na dodaniu następujących dwóch wierszy do kodu znajdującego się za metodą Page_Load niestandardowej strony 404.
Response.Status = "404 Not Found";
Response.StatusCode = 404;
To nie działa. Strona nadal zwraca 200 OK. Zauważyłem jednak, że jeśli na stałe zakoduję następujący kod w kodzie projektowym, będzie on działał poprawnie.
<asp:Content ID="ContentMain" ContentPlaceHolderID="ContentPlaceHolderMaster" runat="server">
<%
Response.Status = "404 Not Found";
Response.StatusCode = 404;
%>
... Much more code ...
</asp:content>
Strona korzysta ze strony wzorcowej. I konfiguruję niestandardowe strony błędów w moim pliku web.config. Naprawdę wolałbym użyć kodu stojącego za opcją, ale nie wydaje mi się, aby działało bez umieszczenia hackowania kodu wbudowanego w projekcie / układzie.
źródło
Odpowiedzi:
Rozwiązanie:
Okazało się, że problemem było użycie strony wzorcowej. Uruchomiłem go, ustawiając kod stanu później w cyklu życia stron, oczywiście renderowanie strony wzorcowej było resetowane, więc nadpisałem metodę renderowania i ustawiłem ją po zakończeniu renderowania.
protected override void Render(HtmlTextWriter writer) { base.Render(writer); Response.StatusCode = 404; }
Można by wykonać więcej pracy, aby dowiedzieć się, kiedy dokładnie strona wzorcowa ustawia status, ale zostawię to Tobie.
Oryginalny post:
Udało mi się sprawić, że testowa aplikacja internetowa działa dobrze, a przynajmniej wyświetliła niestandardową stronę błędu i zwróciła kod stanu 404. Nie mogę powiedzieć, co jest nie tak z twoją aplikacją, ale mogę ci powiedzieć, co zrobiłem:
1) Edytowano plik web.config pod kątem błędów niestandardowych:
2) Dodano stronę 404.aspx i ustawiono kod stanu na 404.
O to chodzi, jeśli przejdę do dowolnego rozszerzenia strony, które jest przetwarzane przez Asp.Net i nie istnieje, mój dziennik skrzypka wyraźnie pokazuje 404, oto nagłówek:
Jeśli teraz przejdę do strony, która nie jest przetwarzana przez Asp.Net, na przykład do pliku htm, strona niestandardowa nie jest wyświetlana, a 404 skonfigurowany przez IIS jest wyświetlany.
Oto post, który zawiera więcej szczegółów, które mogą być przydatne dla Ciebie i Twojego problemu, mój test przekierowuje na nową stronę, więc adres URL żądanego pliku jest prawie utracony (z wyjątkiem tego, który znajduje się w ciągu zapytania) .
Niestandardowe strony błędów Google 404 i .NET
Odpowiedź szpiega nagłówka:
HTTP/1.1 404 Not Found Date: Sun, 07 Dec 2008 06:21:20 GMT
źródło
.html
niestandardowych stron błędów?Miałem podobny problem, chciałem wyświetlić niestandardową stronę jako 404 (czyli ASPX) i działała dobrze na hoście lokalnym, ale gdy tylko zdalny gość połączy się, otrzyma ogólny IIS 404.
Rozwiązaniem było dodanie
Response.TrySkipIisCustomErrors = true;
Przed zmianą Response.StatusCode.
Znalezione przez Rick Strahl http://www.west-wind.com/weblog/posts/745738.aspx
źródło
Rozwiązanie IIS 7 polega po prostu na dodaniu tego do pliku web.config:
<system.webServer> <httpErrors existingResponse="Replace"> <remove statusCode="500" subStatusCode="-1" /> <remove statusCode="404" subStatusCode="-1" /> <error statusCode="404" prefixLanguageFilePath="" path="404.htm" responseMode="File" /> <error statusCode="500" prefixLanguageFilePath="" path="500.htm" responseMode="File" /> </httpErrors> </system.webServer>
http://forums.asp.net/t/1563128.aspx/1
źródło
Spróbuj wywołać Response.End (), aby pominąć renderowanie ...
Response.Status = "404 Not Found"; Response.StatusCode = 404; Response.End(); return;
źródło
Po wielu testach i rozwiązywaniu problemów okazuje się, że niektórzy dostawcy hostingu mogą zakłócać kod zwrotny. Udało mi się to obejść, stosując „hack” w treści.
<% // This code is required for host that do special 404 handling... Response.Status = "404 Not Found"; Response.StatusCode = 404; %>
Umożliwi to stronie zwrócenie poprawnego kodu powrotu bez względu na wszystko.
źródło
Udało mi się obejść ten problem, używając następującej konfiguracji w formularzach internetowych asp.net przy użyciu platformy .NET 3.5.
Wzorzec, który zaimplementowałem, omija niestandardowe rozwiązanie przekierowania .NET w pliku web.config, ponieważ napisałem własne, aby obsługiwać wszystkie scenariusze z poprawnym kodem stanu HTTP w nagłówku.
Po pierwsze, sekcja customErrors w pliku web.config wygląda następująco:
<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm" />
Ta konfiguracja zapewnia, że tryb CustomErrors jest włączony, ustawienie, którego będziemy potrzebować później, i zapewnia opcję all-else-fail dla defaultRedirect error.htm. Przyda się to, gdy nie mam modułu obsługi określonego błędu lub jest coś w rodzaju zerwanego połączenia z bazą danych.
Po drugie, oto globalne zdarzenie asax Error:
protected void Application_Error(object sender, EventArgs e) { HandleError(); } private void HandleError() { var exception = Server.GetLastError(); if (exception == null) return; var baseException = exception.GetBaseException(); bool errorHandled = _applicationErrorHandler.HandleError(baseException); if (!errorHandled) return; var lastError = Server.GetLastError(); if (null != lastError && HttpContext.Current.IsCustomErrorEnabled) { Elmah.ErrorSignal.FromCurrentContext().Raise(lastError.GetBaseException()); Server.ClearError(); } }
Ten kod przekazuje odpowiedzialność za obsługę błędu na inną klasę. Jeśli błąd nie jest obsługiwany, a CustomErrors jest włączony, oznacza to, że mamy przypadek, w którym jesteśmy na produkcji i jakoś błąd nie został obsłużony. Wyczyścimy to tutaj, aby użytkownik nie mógł go zobaczyć, ale zaloguj się do Elmah, abyśmy wiedzieli, co się dzieje.
Klasa applicationErrorHandler wygląda następująco:
public bool HandleError(Exception exception) { if (exception == null) return false; var baseException = exception.GetBaseException(); Elmah.ErrorSignal.FromCurrentContext().Raise(baseException); if (!HttpContext.Current.IsCustomErrorEnabled) return false; try { var behavior = _responseBehaviorFactory.GetBehavior(exception); if (behavior != null) { behavior.ExecuteRedirect(); return true; } } catch (Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); } return false; }
Ta klasa zasadniczo używa wzorca polecenia, aby zlokalizować odpowiednią procedurę obsługi błędów dla typu zgłoszonego błędu. Ważne jest, aby używać Exception.GetBaseException () na tym poziomie, ponieważ prawie każdy błąd zostanie opakowany w wyjątek wyższego poziomu. Na przykład wykonanie „rzutu nowego System.Exception ()” z dowolnej strony aspx spowoduje odebranie wyjątku HttpUnhandledException na tym poziomie, a nie System.Exception.
Kod „fabryczny” jest prosty i wygląda następująco:
public ResponseBehaviorFactory() { _behaviors = new Dictionary<Type, Func<IResponseBehavior>> { {typeof(StoreException), () => new Found302StoreResponseBehavior()}, {typeof(HttpUnhandledException), () => new HttpExceptionResponseBehavior()}, {typeof(HttpException), () => new HttpExceptionResponseBehavior()}, {typeof(Exception), () => new Found302DefaultResponseBehavior()} }; } public IResponseBehavior GetBehavior(Exception exception) { if (exception == null) throw new ArgumentNullException("exception"); Func<IResponseBehavior> behavior; bool tryGetValue = _behaviors.TryGetValue(exception.GetType(), out behavior); //default value here: if (!tryGetValue) _behaviors.TryGetValue(typeof(Exception), out behavior); if (behavior == null) Elmah.ErrorSignal.FromCurrentContext().Raise( new Exception( "Danger! No Behavior defined for this Exception, therefore the user might have received a yellow screen of death!", exception)); return behavior(); }
W końcu mam rozszerzalny schemat obsługi błędów. W każdym ze zdefiniowanych „zachowań” mam niestandardową implementację dla typu błędu. Na przykład wyjątek HTTP zostanie sprawdzony pod kątem kodu stanu i odpowiednio obsłużony. Kod stanu 404 będzie wymagał Server.Transfer zamiast Request.Redirect, wraz z odpowiednim kodem stanu zapisanym w nagłówku.
Mam nadzieję że to pomoże.
źródło
Możesz użyć poniższego kodu:
Response.TrySkipIisCustomErrors = True Response.Status = "404 Not Found" Response.AddHeader("Location", "{your-path-to-your-404-page}")
źródło