2008-12-07 12 views
74

Después de intentar configurar mi sitio para las Herramientas para webmasters de Google, encontré que mi página personalizada ASP.NET 404 no devolvía el código de estado 404. Mostró la página personalizada correcta y le dijo al navegador que todo está bien. Esto se considera un 404 suave o falso 404. A Google no le gusta esto. Así que encontré muchos artículos sobre el tema, pero la solución que quería no parecía funcionar.ASP.NET personalizado 404 Devolución 200 OK En lugar de 404 No encontrado

La solución que quiero trabajar es agregar las dos líneas siguientes al código detrás del método Page_Load de la página 404 personalizada.

Response.Status = "404 Not Found"; 
Response.StatusCode = 404; 

Esto no funciona. La página aún devuelve 200 OK. Sin embargo, encontré que si codificaba el código siguiente en el código de diseño funcionaría correctamente.

<asp:Content ID="ContentMain" ContentPlaceHolderID="ContentPlaceHolderMaster" runat="server"> 

<% 
    Response.Status = "404 Not Found"; 
    Response.StatusCode = 404; 
%> 

... Much more code ... 

</asp:content> 

La página utiliza una página maestra. Y estoy configurando páginas de error personalizadas en mi web.config. Preferiría usar la opción de código detrás, pero parece que no puedo hacer que funcione sin poner un código en línea en el diseño/diseño.

+0

¿Qué significa el navegador? Uso el complemento Header Spy para Firefox. –

+0

Header Spy Respuesta: HTTP/1.1 404 No encontrado Fecha: Dom, 07 Dec 2008 06:21:20 GMT –

+0

¿Estás utilizando una página maestra? Tal vez eso es todo. Probaré una página sin utilizar una página maestra ... –

Respuesta

68

Solución:

El problema, se vio después, fue el uso de la página maestra. Conseguí que funcionara estableciendo el código de estado más adelante en el ciclo de vida de las páginas, obviamente el renderizado de la página maestra estaba restableciéndolo, así que anulé el método de renderizado y lo configuré después de que se completara el renderizado.

protected override void Render(HtmlTextWriter writer) 
{ 
    base.Render(writer); 
    Response.StatusCode = 404; 
} 

Más trabajo se podría hacer para saber exactamente cuando la página principal es establecer el estado, pero yo lo dejo a ti.


Post original:

que era capaz de conseguir una aplicación web de prueba que funciona bien, así que, al menos, aparece la página personalizada de error y devuelve un código de estado 404. No puedo decirle lo que está mal con su aplicación, pero te puedo decir lo que hice:

1) Editado el web.config de errores personalizados:

<customErrors mode="On"> 
    <error statusCode="404" redirect="404.aspx"/> 
</customErrors> 

2) se ha añadido una página 404.aspx y establecer el código de estado a 404.

public partial class _04 : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     Response.StatusCode = 404; 
    } 
} 

eso es todo, si voy a cualquier página exte nsion que es procesado por Asp.Net y no existe, mi registro violinista muestra claramente un 404, aquí es el encabezado:

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 

Ahora si voy a una página que no es procesado por Asp .Net, como un archivo htm, la página personalizada no se muestra y se muestra el 404 configurado por IIS.

Aquí hay una publicación que entra en algunos detalles más que pueden ser útiles para usted y su problema, mi prueba hace un redireccionamiento a la nueva página por lo que la URL del archivo solicitado se pierde (excepto en la cadena de consulta).

Google 404 and .NET Custom Error Pages

Header Spy Respuesta:

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

** Header Spy ** es complemento _Header Spy para Firefox_ – Kiquenet

+0

¿Cómo funciona esto para páginas de error personalizadas '.html' estáticas? – ebyrob

5

Después de muchas pruebas y resolución de problemas parece que ciertos proveedores de alojamiento pueden interferir con el código de retorno. Pude solucionar esto aplicando un "truco" en el contenido.

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

Esto permitirá que la página devuelva el código de retorno correcto pase lo que pase.

27

tuve un problema similar que quiero mostrar una página personalizada como 404 (que es ASPX) y funcionó bien en el servidor local, pero tan pronto como un visitante remoto conectado que obtendrían el IIS genérico 404.

La solución a esto era agregar

Response.TrySkipIisCustomErrors = true; 

Antes de cambiar el Response.StatusCode.

encontrado a través de Rick Strahl http://www.west-wind.com/weblog/posts/745738.aspx

9

intente llamar Response.End() para saltar la representación ...

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

La solución de IIS 7 es simplemente agregar esto a su archivo 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

+3

¡Trabajó para mí! Aquí solo funcionó la solución, probablemente debido a la versión que usted nota ... Tenga en cuenta que solo puede usar archivos .htm estáticos con esta solución. – squarecandy

+0

¡Esto funcionó de manera excelente! Gracias por la solución. –

0

que era capaz de moverse este problema mediante el uso de la siguiente configuración en formularios web asp.net utilizando .NET 3.5.

El patrón que he implementado omite la solución de redireccionamiento personalizado de .NET en el archivo web.config, ya que he escrito el mío para manejar todos los escenarios con el código de estado HTTP correcto en el encabezado.

En primer lugar, la sección customErrors del web.config se ve así:

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

Esta configuración asegura que el modo CustomErrors está activada, un entorno que necesitaremos más adelante, y proporciona un todo-cosa-falla opción para el defaultRedirect de error.htm. Esto será útil cuando no tengo un controlador para el error específico, o hay algo parecido a una conexión de base de datos rota.

En segundo lugar, aquí está el caso asax error global:

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

Este código está pasando fuera de la responsabilidad de manejar el error a otra clase. Si no se maneja el error y CustomErrors está activado, eso significa que tenemos un caso en el que estamos en producción y de alguna manera no se ha manejado un error. Lo borraremos aquí para evitar que el usuario lo vea, pero inicie sesión en Elmah para saber qué está pasando.

clase El applicationErrorHandler se ve así:

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

Esta clase esencialmente utiliza el patrón de comandos para localizar el controlador de errores apropiado para el tipo de error que se emitió. Es importante usar Exception.GetBaseException() en este nivel, ya que casi todos los errores se envolverán en una excepción de nivel superior. Por ejemplo, si se ejecuta "throw new System.Exception()" desde cualquier página aspx, se recibirá una HttpUnhandledException en este nivel, no una excepción System.Exception.

El código "fábrica" ​​es simple y se ve así:

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

Al final, tengo una configuración de sistema de gestión de errores extensible. En cada uno de los "comportamientos" definidos, tengo una implementación personalizada para el tipo de error. Por ejemplo, se inspeccionará una excepción Http para el código de estado y se manejará de manera adecuada. Un código de estado 404 requerirá un Server.Transfer en lugar de un Request.Redirect, junto con el código de estado apropiado escrito en el encabezado.

Espero que esto ayude.

Cuestiones relacionadas