我试图找出一种方法来捕获在页面生命周期中Render()
方法之前发生的特定类型的所有异常,将其存储并绕过YSOD错误处理程序。然后在Render()
的覆盖中执行以下操作:
protected override void Render(HtmlTextWriter writer)
{
if(ReqObjectException != null)
{
base.Render(writer);
}
else
{
Log.Error("Missing required object in Base Control", ReqObjectException, this);
writer.WriteLine("<!--");
foreach(var exception in ReqObjectExceptions)
{
writer.WriteLine(ex.Message);
}
writer.WriteLine("-->");
}
}
这里的想法是,我将一些动态控件添加到页面中,并且有时需要它们具有一些关联的数据。现在,如果内容作者忘记附加相关数据,他们将获得YSOD并大吃一惊。
这里的想法是页面的其余部分继续起作用,并且有一个日志条目和指向该问题的HTML注释。也许我将创建一些警告对话框,以使他们知道缺少某些内容。
最佳答案
感谢nsgocev的MVC实现,它使我走上了正确的道路。
对于Web窗体,相同类型的内容不起作用。幸运的是,我们所有的子布局不会直接在Page_Init或Page_Load中执行其逻辑。基本Sublayout具有以下方法:
protected virtual void Page_Init(object sender, EventArgs e)
{
this.Initialize();
}
protected virtual void Initialize()
{
this.Bind();
}
protected virtual void Bind()
{
}
派生的子布局在Bind()或Initialize()中执行所有逻辑。我用try catch将Initialize包装在Page_Init中,并添加了一个名为Exeption的类属性。
protected virtual void Page_Init(object sender, EventArgs e)
{
if (CommonConfig.SuppressRenderingExceptions)
{
try
{
this.Initialize();
}
catch (Exception ex)
{
this.Exception = ex;
}
}
else
{
this.Initialize();
}
}
然后我覆盖了Render()
protected override void Render(HtmlTextWriter writer)
{
if (this.Exception == null)
{
try
{
base.Render(writer);
}
catch (Exception ex)
{
this.Exception = ex;
}
}
if (this.Exception != null)
{
writer.BeginRender();
MRenderingManager.HandleRenderingException(writer, this.Exception, this.BaseTypeName, this);
writer.EndRender();
}
}
如果有异常,则在Page_Init或base.Render()中,我们将执行HandleRenderingException()。
public static void HandleRenderingException(TextWriter writer, Exception ex, string baseTypeName, object owner)
{
Log.Error("Rendering Error", ex, owner);
if (Context.PageMode.IsNormal)
{
writer.WriteLine("<!--");
writer.WriteLine("[Your comment or serialized exception]");
writer.WriteLine("-->");
}
else
{
writer.WriteLine("<div class=\"rendering-exception\">");
writer.WriteLine("[Your comment or serialized exception]");
writer.WriteLine("</div>");
}
HttpContext.Current.Server.ClearError();
}
这样,如果内容作者添加了损坏的控件,他们将在页面编辑器/预览模式下获得有用的消息。
关于c# - 在页面生命周期中的Render()之前发生的错误中重写YSOD,然后将异常内容作为该控件的HTML注释写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32770068/