ASP.NET пользовательский 404 возврат 200 ОК вместо 404 не найден
после попытки настроить мой сайт для Google Webmaster Tools я обнаружил, что мой пользовательский ASP.NET страница 404 не возвращала код состояния 404. Он отобразил правильную пользовательскую страницу и сказал браузеру, что все в порядке. Это считается мягким 404 или ложным 404. Google это не нравится. Поэтому я нашел много статей по этому вопросу, но решение, которое я хочу, похоже, не работает.
решение, которое я хочу работать, - это добавление следующих двух строк в код метода Page_Load пользовательскую страницу 404.
Response.Status = "404 Not Found";
Response.StatusCode = 404;
это не сработает. Страница по-прежнему возвращает 200 OK. Однако я обнаружил, что если я жестко закодирую следующий код в код дизайна, он будет работать правильно.
<asp:Content ID="ContentMain" ContentPlaceHolderID="ContentPlaceHolderMaster" runat="server">
<%
Response.Status = "404 Not Found";
Response.StatusCode = 404;
%>
... Much more code ...
</asp:content>
страница использует главную страницу. И я настраиваю пользовательские страницы ошибок в своем интернете.конфиг. Я бы предпочел использовать код за опцией, но я не могу заставить его работать, не помещая встроенный код взлома в дизайн / макет.
6 ответов:
устранение:
проблема, как оказалось, заключалась в использовании главной страницы. Я получил его для работы, установив код состояния позже в жизненном цикле страниц, очевидно, рендеринг главной страницы сбрасывал его, поэтому я переопределил метод рендеринга и установил его после завершения рендеринга.
protected override void Render(HtmlTextWriter writer) { base.Render(writer); Response.StatusCode = 404; }можно было бы сделать больше работы, чтобы точно узнать, когда главная страница устанавливает статус, но я оставлю это вы.
Исходный Пост:
я смог заставить тестовое веб-приложение работать нормально, ну, по крайней мере, он отобразил пользовательскую страницу ошибок и вернул код состояния 404. Я не могу сказать вам, что не так с вашим приложением, но я могу сказать вам, что я сделал:
1) редактировать веб.конфигурация для пользовательских ошибок:
<customErrors mode="On"> <error statusCode="404" redirect="404.aspx"/> </customErrors>2) добавлено 404.страница aspx и установите код состояния в 404.
public partial class _04 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Response.StatusCode = 404; } }вот об этом, если я перейду к любому расширению страницы, которое обрабатывается Asp.Net и не существует, мой скрипач журнал четко показывает 404, вот заголовок:
HTTP/1.1 404 Not Found Server: Microsoft-IIS/5.1 Date: Sun, 07 Dec 2008 06:04:13 GMT X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private Content-Type: text/html; charset=utf-8 Content-Length: 533теперь, если я перейду на страницу, которая не обрабатывается Asp.Net как и htm-файл, пользовательская страница не отображается, и отображается 404, настроенный IIS.
вот сообщение, которое входит в некоторые более подробные сведения, которые могут быть полезны для вас и ваша проблема, мой тест делает перенаправление на новую страницу, поэтому url-адрес запрошенного файла в значительной степени потерян (за исключением его в строке запроса).
Google 404 и .NET пользовательские страницы ошибок
Заголовок Ответа Шпиона:
HTTP/1.1 404 Not Found Date: Sun, 07 Dec 2008 06:21:20 GMT
У меня была аналогичная проблема, я хочу показать пользовательскую страницу как 404 (которая является ASPX), и она отлично работала на localhost, но как только удаленный посетитель подключится, они получат общий IIS 404.
решение этой проблемы было добавить
Response.TrySkipIisCustomErrors = true;перед изменением ответа.свойство statusCode.
найдено через Rick Strahl http://www.west-wind.com/weblog/posts/745738.aspx
решение IIS 7-это просто добавить это в свой веб.конфигурационный файл:
<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>
попробуйте вызвать ответ.End () для пропуска рендеринга...
Response.Status = "404 Not Found"; Response.StatusCode = 404; Response.End(); return;
после долгих испытаний и устранения неполадок кажется, что некоторые хостинг-провайдеры могут вмешиваться в код возврата. Я смог обойти это, применив " Хак " в содержании.
<% // This code is required for host that do special 404 handling... Response.Status = "404 Not Found"; Response.StatusCode = 404; %>Это позволит странице вернуть правильный код возврата, несмотря ни на что.
я смог обойти эту проблему, используя следующую настройку в asp.net веб-формы с использованием .NET 3.5.
шаблон, который я реализовал, обходит пользовательское решение перенаправления .NET в интернете.конфигурация, как я написал свой собственный, чтобы обрабатывать все сценарии с правильным кодом состояния HTTP в заголовке.
во-первых, веб.раздел customErrors конфигурации выглядит следующим образом:
<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm" />Эта настройка гарантирует, что режим CustomErrors установлен в on, что нам понадобится позже, и предоставляет все остальное-не удается вариант для defaultRedirect ошибки.htm. Это пригодится, когда у меня нет обработчика для конкретной ошибки, или есть что-то вроде сломанного соединения с базой данных.
во-вторых, вот глобальное событие ошибки asax:
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(); } }этот код передает ответственность за обработку ошибки другому классу. Если ошибка не обрабатывается и CustomErrors включен, это означает, что у нас есть случай, когда мы на производстве и как-то ошибка не была обработана. Мы очистим его здесь, чтобы пользователь не видел его, но зарегистрируйте его в Elmah, чтобы мы знали, что происходит.
класс applicationErrorHandler выглядит так:
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; }этот класс по существу использует шаблон команды, чтобы найти соответствующий обработчик ошибок для типа ошибки, которая выдается. Важно использовать исключение.GetBaseException () на этом уровне, потому что почти каждая ошибка будет обернута в исключении более высокого уровня. Например, делать "бросок новой системы".Исключение () " из любой страницы aspx приведет к получению HttpUnhandledException на этом уровне, а не в системе.Исключение.
код "фабрики" прост и выглядит так:
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(); }в конце концов, у меня есть расширяемая схема обработки ошибок настройки. В каждом из "поведений", которые определены, у меня есть пользовательская реализация для типа ошибки. Например, исключение Http будет проверено на наличие кода состояния и обработано соответствующим образом. Для кода состояния 404 потребуется сервер.Передача вместо запроса.Перенаправление вместе с соответствующим кодом состояния, записанным в заголовке.
надеюсь, что это помогает.
Comments