在我们的
Global.asax
文件中,我们有:
protected void Application_Error()
{
Errors.Functions.HandleException(HttpContext.Current);
}
出现
404
错误时,将执行以下代码:
context.Server.Transfer("~/pages/errors/404.aspx");
context.ClearError();
context.ApplicationInstance.CompleteRequest();
这对于每个 404 异常都绝对有效。 但是,我们在日志中看到对不存在的路径的奇怪请求,例如:
https://www.example.com/en/meta.json
访问此页面将提供如上所述的正常
404
响应页面,并且不会引发任何异常。
但是,这些请求(我猜是来自某些漏洞扫描程序或爬虫)每天都会抛出此异常:
TYPE: HttpException
BASE TYPE: ExternalException
MESSAGE: Error executing child request for /pages/errors/404.aspx.
SOURCE:
System.Web
STACK TRACE:
at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
at System.Web.HttpServerUtility.Execute(String path, TextWriter writer, Boolean preserveForm)
at System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm)
at System.Web.HttpServerUtility.Transfer(String path)
at C3.Code.Controls.Application.Errors.Functions.HandleException(HttpContext context) in ...\HandleHTTPException.cs:line 81
81号线是
context.Server.Transfer(..
线。
内部异常是:
TYPE: NullReferenceException
BASE TYPE: SystemException
MESSAGE:
Object reference not set to an instance of an object.
SOURCE:
C3Alpha2
STACK TRACE:
at C3.Pages.Errors._404.Page_Load(Object sender, EventArgs e) in ...\Pages\Errors\404.aspx.cs:line 12
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
第 12 行位于
Page_Load
行中:
public partial class _404 : System.Web.UI.Page
{
public Master_Pages.Main MP => (Master_Pages.Main) Master;
protected void Page_Load(object sender, EventArgs e)
{
MP.IsErrorPage = true;
MP.SEOPageHeader.Title = "File not found";
}
}
抛出错误的请求是正常的
HTTP GET
请求,并且记录有关标头等的详细信息不会显示任何看起来太不寻常的内容。
有谁知道什么可能导致抛出这些异常?
编辑:根据要求,404.aspx页面:
<%@ Page Language="C#" ValidateRequest="false" EnableViewState="false" MasterPageFile="~/Pages/Master Pages/Main.master" AutoEventWireup="True" Inherits="C3.Pages.Errors._404" Codebehind="404.aspx.cs" %>
<asp:Content ID="Content1" ContentPlaceHolderID="Head" runat="server">
<base href="<%= C3.Code.Settings.Hosts.SecureRootDomain %>"/>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="server">
<span class="preH1">Ahhhh nuts!</span>
<h1>We Couldn't Find That!</h1>
<div class="singleCol">
<Controls:ResponsiveImageFixedSize
runat="server"
ImagePath="/errors/404.jpg"
Width="700"
/>
<p>The server returned an HTTP 404 error. That requested URL could not be found.</p>
</div>
</asp:Content>
可能原因:
这表明当 Page_Load 事件执行时,你的
MP
属性可能是 null
。如果 Server.Transfer
未正确完全重新初始化页面生命周期,则可能会发生这种情况,尤其是在转移到使用母版页的页面时。
可能的解决方案:
使用
Response.Redirect
代替Server.Transfer
来预防NullReferenceException
:
虽然
Server.Transfer
保持 URL 不变,但 Response.Redirect
更改浏览器中的 URL 并执行新请求。此方法通常更安全,因为它完全重新初始化页面生命周期,避免了剩余上下文的问题。
context.Response.Redirect("~/pages/errors/404.aspx", true);
context.ClearError();
context.ApplicationInstance.CompleteRequest();
使用前检查
null
MP
:
如果您希望继续使用
Server.Transfer
,则应在 null
方法中使用 MP
之前添加 Page_Load
检查:
protected void Page_Load(object sender, EventArgs e)
{
if (MP != null)
{
MP.IsErrorPage = true;
MP.SEOPageHeader.Title = "File not found";
}
}
注意:切换到
Response.Redirect
可能是最可靠的解决方案,因为它会强制对错误页面发出新的、干净的请求,从而消除剩余或不完整上下文的任何潜在问题。