После попытки настроить мой сайт для инструментов Google для веб-мастеров я обнаружил, что моя пользовательская страница 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>
На странице используется эталонная страница. И я настраиваю пользовательские страницы ошибок в своем web.config. Я бы предпочел использовать вариант кода позади, но я не могу заставить его работать, не вставив встроенный код взлома в дизайн / макет.
Заголовочный шпионский ответ: HTTP / 1.1 404 Not Found Дата: вс, 7 декабря 2008 г., 06:21:20 по Гринвичу
Вы используете главную страницу? Может это все. Я попробую страницу без главной страницы ...
Нет, я не был, но я тоже могу быстро проверить, я попробую с одним.
Ага, вот и все! Мастер-страница вызвала 200 OK
Так что мне нужно разобраться в этой части, интересно, как исправить?





Решение:
Проблема, как выяснилось, заключалась в использовании главной страницы. Я заставил его работать, установив код состояния позже в жизненном цикле страниц, очевидно, рендеринг главной страницы сбрасывал его, поэтому я переопределил метод рендеринга и установил его после завершения рендеринга.
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
Response.StatusCode = 404;
}
Чтобы точно определить, когда главная страница устанавливает статус, можно провести дополнительную работу, но я оставлю это вам.
Исходное сообщение:
Мне удалось заставить тестовое веб-приложение работать нормально, ну, по крайней мере, оно отображало настраиваемую страницу с ошибкой и возвращало код состояния 404. Я не могу сказать вам, что не так с вашим приложением, но могу сказать, что я сделал:
1) Отредактировал web.config для пользовательских ошибок:
<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
Как это работает для статических пользовательских страниц ошибок .html?
После долгого тестирования и устранения неполадок выяснилось, что некоторые хостинг-провайдеры могут вмешиваться в код возврата. Я смог обойти это, применив «взлом» в содержании.
<%
// This code is required for host that do special 404 handling...
Response.Status = "404 Not Found";
Response.StatusCode = 404;
%>
Это позволит странице вернуть правильный код возврата, несмотря ни на что.
У меня была аналогичная проблема, я хочу показать настраиваемую страницу как 404 (это ASPX), и она отлично работала на localhost, но как только удаленный посетитель подключился, они получали общий IIS 404.
Решением было добавить
Response.TrySkipIisCustomErrors = true;
Перед изменением Response.StatusCode.
Найдено через Rick Strahl http://www.west-wind.com/weblog/posts/745738.aspx
Попробуйте вызвать Response.End (), чтобы пропустить рендеринг ...
Response.Status = "404 Not Found";
Response.StatusCode = 404;
Response.End();
return;
Решение IIS 7 - просто добавить это в ваш файл 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
Сработало у меня! Единственное решение, которое сработало, вероятно, из-за версии, которую вы заметили ... Имейте в виду: вы можете использовать только статические файлы .htm с этим решением.
Мне удалось обойти эту проблему, используя следующую настройку в веб-формах asp.net с использованием .NET 3.5.
Реализованный мной шаблон обходит пользовательское решение перенаправления .NET в файле web.config, поскольку я написал свой собственный для обработки всех сценариев с правильным кодом состояния HTTP в заголовке.
Во-первых, раздел customErrors web.config выглядит так:
<customErrors mode = "RemoteOnly" defaultRedirect = "~/error.htm" />
Эта настройка гарантирует, что режим CustomErrors включен, параметр, который нам понадобится позже, и предоставляет параметр all-else-fails для defaultRedirect файла error.htm. Это пригодится, когда у меня нет обработчика для конкретной ошибки или есть что-то вроде разорванного соединения с базой данных.
Во-вторых, вот глобальное событие 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();
}
}
Этот код перекладывает ответственность за обработку ошибки на другой класс. Если ошибка не обрабатывается и 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;
}
Этот класс по существу использует шаблон команды для поиска подходящего обработчика ошибок для типа выданной ошибки. На этом уровне важно использовать Exception.GetBaseException (), потому что почти каждая ошибка будет заключена в исключение более высокого уровня. Например, выполнение команды «throw new System.Exception ()» с любой страницы aspx приведет к получению исключения HttpUnhandledException на этом уровне, а не System.Exception.
«Заводской» код прост и выглядит так:
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 потребуется Server.Transfer вместо Request.Redirect, а также соответствующий код состояния, записанный в заголовке.
Надеюсь это поможет.
Вы можете использовать приведенный ниже код:
Response.TrySkipIisCustomErrors = True
Response.Status = "404 Not Found"
Response.AddHeader("Location", "{your-path-to-your-404-page}")
Что сообщает браузер? Я использую аддон Header Spy для Firefox.