2008-12-07 53 views
74

尝试为Google网站管理员工具设置我的网站后,我发现我的自定义ASP.NET 404页面未返回404状态码。它显示了正确的自定义页面,并告诉浏览器一切正常。这是考虑软404或虚假404。谷歌不喜欢这个。所以我发现了很多关于这个问题的文章,但我想要的解决方案似乎并不奏效。ASP.NET自定义404返回200确定而不是404未找到

我想要的解决方案是将以下两行添加到自定义404页面的Page_Load方法后面的代码中。

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

浏览器状态如何?我使用Firefox的插件Header Spy。 – 2008-12-07 06:17:25

+0

标头间谍响应: HTTP/1.1 404未找到 日期:Sun,07 Dec 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; 
} 

更多的工作可以做,以找出究竟当母版页设置状态,但我会留给你。


原贴:

我能得到一个测试web应用程序正常工作,那么它至少显示自定义错误页,并返回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; 
    } 
} 

那一下,如果我去到任何页面EXTE由Asp.Net处理,不存在nsion,我拉琴日志清楚地显示出一个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 

现在,如果我去不是由天冬氨酸处理的页面.Net,就像一个htm文件一样,自定义页面不显示,并且显示由IIS配置的404。

这里有一些可能对你和你的问题有用的更多细节,我的测试确实做了一个重定向到新页面,所以请求的文件的URL几乎丢失了(除了在查询字符串)。

Google 404 and .NET Custom Error Pages

头间谍响应:

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之前。

通过里克施特拉尔找到http://www.west-wind.com/weblog/posts/745738.aspx

9

尝试到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

我是能够得到解决通过使用.NET 3.5的asp.net webforms中的以下设置来解决此问题。

我实现的模式绕过在web.config .NET的自定义重定向解决方案,我写我自己来处理所有的场景头中具有正确的HTTP状态代码。

首先,web.config中的部分的customErrors看起来是这样的:

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

这种设置保证的customErrors模式设置为上,后来我们就需要设置,并提供了一个所有其他人,失败选项为error.htm的defaultRedirect。这会派上用场的时候我没有特定的错误处理程序,或有沿着破碎的数据库连接线的东西。

其次,这里是全球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()是很重要的,因为几乎每个错误都会被封装在一个更高级别的异常中。例如,从任何aspx页面执行“throw new System.Exception()”将导致在此级别接收到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,以及写入标题中的相应状态代码。

希望这会有所帮助。

相关问题