2008-12-07 7 views
74

После попытки настроить мой сайт для Инструментов Google для веб-мастеров, я обнаружил, что моя пользовательская страница ASP.NET 404 не возвращала код статуса 404. Он отобразил правильную страницу и сказал браузеру, что все в порядке. Это считается мягким 404 или ложным 404. Google не нравится это. Поэтому я нашел много статей по этому вопросу, но решение, которое я хочу, похоже, не работает.ASP.NET Custom 404 Возвращение 200 OK Вместо 404 Не найдено

Решение, которое я хочу использовать, заключается в добавлении следующих двух строк в код позади метода 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. Я бы предпочел использовать код позади опции, но я не могу заставить его работать, не вставляя строчный код взлома в дизайн/макет.

+0

Что говорит браузер? Я использую addon Header Spy для Firefox. – 2008-12-07 06:17:25

+0

Header Spy Response: HTTP/1.1 404 Не найдено Дата: Вс, 07 Дек 2008 06:21:20 GMT – 2008-12-07 06:21:54

+0

Вы используете мастер-страницу? Может быть, все. Я попробую страницу без использования главной страницы ... – 2008-12-07 06:23:12

ответ

68

Решение:

Проблема, как оказалось, было использование главной страницы. Я получил его для работы, установив код состояния позже в жизненном цикле страниц, очевидно, что рендеринг главной страницы сбросил его, поэтому я переопределил метод рендеринга и установил его после завершения рендеринга.

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

Thats об этом, если я пойду на любую страницу Exte nsion, который обрабатывается 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 and .NET Custom Error Pages

Заголовок Spy Ответ:

HTTP/1.1 404 Not Found 
Date: Sun, 07 Dec 2008 06:21:20 GMT 
5

После долгих испытаний и поиска неисправностей это кажется, что некоторые хостинг-провайдеров могут вмешиваться в код возврата. Я смог обойти это, применив «хак» в контенте.

<% 
// This code is required for host that do special 404 handling... 
Response.Status = "404 Not Found"; 
Response.StatusCode = 404; 
%> 

Это позволит странице вернуть правильный код возврата независимо от того, что.

27

У меня была аналогичная проблема, я хочу, чтобы показать пользовательскую страницу как 404 (который ASPX), и она работала отлично на локальный, но как только удаленный пользователь подключен они будут получать общий IIS 404.

Решением к этому было бы добавить

Response.TrySkipIisCustomErrors = true; 

Перед изменением кода Response.StatusCode.

Найденный через Rick Strahl http://www.west-wind.com/weblog/posts/745738.aspx

9

Try вызова Response.End(), чтобы пропустить рендеринга ...

Response.Status = "404 Not Found"; 
Response.StatusCode = 404; 
Response.End(); 
return; 
12

Решение 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

0

я смог обойти эту проблему, используя следующую настройку в веб-формах asp.net с помощью .NET 3.5.

Шаблон, который я реализовал, обходит специальное настраиваемое решение .NET в файле web.config, поскольку я написал свой собственный, чтобы обрабатывать все сценарии с правильным кодом состояния HTTP в заголовке.

Во-первых, CustomErrors секция Web.config выглядит следующим образом:

<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm" /> 

Эта установка гарантирует, что режим CustomErrors установлен в положение включено, настройки мы будем нуждаться позже, и предоставляет все остальное терпит неудачу, для параметра defaultRedirect error.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; 
     } 

Этот класс в основном использует шаблон команды, чтобы найти соответствующий обработчик ошибок для типа ошибки, которая выдается. Важно использовать 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 вместе с соответствующим кодом состояния, записанным в заголовке.

Надеюсь, это поможет.