Pergunta

Depois de tentar configurar o meu site para o Google Webmaster Tools, descobri que minha página personalizada ASP.NET 404 não estava retornando o código de status 404. É exibida a página personalizada correta e disse o navegador que está tudo OK. Esta é considerar um soft 404 ou falso 404. Google não faz assim. Então, eu encontrei muitos artigos sobre o problema, mas a solução que eu quero não parece trabalho.

A solução que eu quero trabalhar está adicionando as duas linhas a seguir para o código por trás método Page_Load da página 404 personalizada.

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

Esta não funciona. A página ainda retorna 200 OK. Eu encontrei no entanto, que se eu codificar o seguinte código para o código de projeto que vai funcionar corretamente.

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

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

 ... Much more code ...

</asp:content>

A página está usando uma página mestra. E eu estou configurar páginas de erro personalizadas no meu web.config. Eu realmente prefiro usar o código por trás opção, mas eu não consigo fazê-lo funcionar sem colocar um código em linha corte no design / layout.

Foi útil?

Solução

Solução:

O problema, ele saiu, foi o uso da página mestre. Eu tenho que trabalhar, definindo o código de status mais tarde nas páginas de ciclo de vida, obviamente, o processamento da página mestre foi redefini-lo, então eu cancelou o método render e configurá-lo após a prestar estava completa.

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

Mais trabalho poderia ser feito para descobrir exatamente quando a página principal é definir o status, mas vou deixar isso para você.


Original Post:

Eu era capaz de obter um aplicativo de teste da web para funcionar bem, bem, pelo menos exibida a página de erro personalizada e retornou um código de status 404. Eu não posso te dizer o que está errado com seu aplicativo, mas eu posso te dizer o que eu fiz:

1) editou o web.config para erros personalizados:

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

2) Adicionado uma página 404.aspx e definir o código de status para 404.

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

Isso é sobre ele, se eu ir para qualquer extensão de página que é processada por Asp.Net e não existe, meu log violinista mostra claramente a 404, aqui é o cabeçalho:

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

Agora, se eu ir para uma página que não é processado por Asp.Net, como um arquivo htm, a página personalizada não mostra eo 404 que está configurado pelo IIS é exibida.

Aqui está um post que vai para mais alguns detalhes que possam ser de utilidade para você e seu problema, meu teste faz fazer um redirecionamento para a nova página assim que a url do arquivo solicitado está praticamente perdido (excepto o seu no string de consulta).

Google 404 e .NET personalizado páginas de erro

Header Spy resposta:

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

Outras dicas

Eu tive um problema semelhante que eu quero mostrar uma página personalizada como um 404 (que é ASPX) e funcionou muito bem em localhost, mas assim que um visitante remoto conectado eles iriam receber o genérico IIS 404.

A solução para isso foi adicionar

Response.TrySkipIisCustomErrors = true;

Antes de mudar o Response.StatusCode.

A via Rick Strahl http://www.west-wind.com/ weblog / posts / 745738.aspx

O IIS 7 solução é apenas adicionar isso ao seu arquivo 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

Tente chamar Response.End () para pular de renderização ...

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

Depois de muitos testes e resolução de problemas, parece que certos provedores de hospedagem pode interferir com o código de retorno. Eu era capaz de contornar este problema através da aplicação de um "hack" no conteúdo.

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

Isso permitirá que a página para retornar o código de retorno correta não importa o que.

Eu era capaz de contornar esse problema usando a seguinte configuração em asp.net webforms usando .NET 3.5.

O padrão Eu tenho implementado bypasses solução redirecionamento personalizado do .NET no web.config como eu escrevi o meu próprio para lidar com todos os cenários com o código de status HTTP correto no cabeçalho.

Em primeiro lugar, os olhares seção customErrors do web.config assim:

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

Esta configuração garante que o modo CustomErrors estiver ativada, um cenário que vamos precisar mais tarde, e fornece uma opção para o defaultRedirect de Error.htm tudo-else-falha. Isto virá a calhar quando eu não tenho um manipulador para o erro específico, ou há algo ao longo das linhas de uma conexão com o banco quebrado.

Em segundo lugar, aqui está o evento asax erro 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 é fazer passar a responsabilidade de lidar com o erro para outra classe. Se o erro não for manuseado e CustomErrors está ligado, isso significa que temos um caso em que estamos na produção e de alguma forma um erro não foi manipulado. Vamos limpá-la aqui, a fim de impedir que o usuário vê-lo, mas registrá-lo em Elmah por isso sabemos o que está acontecendo.

Os olhares classe applicationErrorHandler como este:

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 classe utiliza essencialmente o padrão de comando para localizar o manipulador de erro apropriada para o tipo de erro que é emitido. É importante usar Exception.GetBaseException () a este nível, porque quase todo erro será envolto em uma exceção de nível superior. Por exemplo, fazendo "throw new System.Exception ()" a partir de qualquer página aspx irá resultar em um HttpUnhandledException sendo recebidos a este nível, não um System.Exception.

O código "fábrica" ??é simples e se parece com isto:

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

No final, eu tenho um erro extensível manipulação configuração esquema. Em cada um dos "comportamentos" que é definido, eu tenho uma implementação personalizada para o tipo de erro. Por exemplo, uma excepção HTTP será inspeccionado para o código de estado e tratadas adequadamente. Um código de status 404 vai exigir um Server.Transfer em vez de um Request.Redirect, juntamente com o código de status apropriado escrito no cabeçalho.

Espero que isso ajude.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top