尝试为Google网站管理员工具设置我的网站后,我发现我的自定义ASP.NET 404页面未返回404状态代码。它显示了正确的自定义页面并告诉浏览器一切正常。这被认为是软404或假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 :(得分:71)
<强>解决方案:强>
事实证明,问题在于使用母版页。我通过在页面生命周期中稍后设置状态代码来实现它,显然主页的呈现正在重置它,所以我覆盖了渲染方法并在渲染完成后设置它。
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文件),则不显示自定义页面,并显示IIS配置的404。
以下是一篇文章,其中介绍了一些可能对您和您的问题有用的细节,我的测试确实会重定向到新页面,因此所请求文件的网址几乎丢失了(除了它在查询字符串)。
Google 404 and .NET Custom Error Pages
标题间谍回复:
HTTP/1.1 404 Not Found
Date: Sun, 07 Dec 2008 06:21:20 GMT
答案 1 :(得分:27)
我有一个类似的问题我想将自定义页面显示为404(这是ASPX)并且它在localhost上工作正常但是只要远程访问者连接它们就会获得通用IIS 404。
解决方法是添加
Response.TrySkipIisCustomErrors = true;
在更改Response.StatusCode之前。
通过Rick Strahl http://www.west-wind.com/weblog/posts/745738.aspx
找到答案 2 :(得分: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>
答案 3 :(得分:10)
尝试调用Response.End()跳过渲染...
Response.Status = "404 Not Found";
Response.StatusCode = 404;
Response.End();
return;
答案 4 :(得分:6)
经过大量测试和故障排除后,似乎某些托管服务提供商可能会干扰返回代码。我通过在内容中应用“黑客”来解决这个问题。
<%
// This code is required for host that do special 404 handling...
Response.Status = "404 Not Found";
Response.StatusCode = 404;
%>
这将允许页面返回正确的返回代码,无论如何。
答案 5 :(得分:1)
通过使用.NET 3.5在asp.net webforms中使用以下设置,我能够解决这个问题。
我实现的模式在web.config中绕过了.NET的自定义重定向解决方案,因为我已经编写了自己的模式来处理标题中包含正确HTTP状态代码的所有方案。
首先,web.config的customErrors部分如下所示:
<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm" />
此设置确保将CustomErrors模式设置为on,这是我们稍后需要的设置,并为error.htm的defaultRedirect提供all-else-failed选项。当我没有特定错误的处理程序时,或者在数据库连接断开的情况下,这会派上用场。
其次,这是全局的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,以及标头中写入的相应状态代码。
希望这有帮助。
答案 6 :(得分:0)
您可以使用以下代码:
Response.TrySkipIisCustomErrors = True
Response.Status = "404 Not Found"
Response.AddHeader("Location", "{your-path-to-your-404-page}")