c# - 在页面生命周期中的Render()之前发生的错误中重写YSOD,然后将异常内容作为该控件的HTML注释写入

标签 c# asp.net error-handling sitecore

我试图找出一种方法来捕获在页面生命周期中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/

相关文章:

c# - 如何将 gridview 绑定(bind)到数组

c# - 在 Asp.Net MVC 5 中获取登录用户的用户 ID

javascript - 使用 JavaScript 实现回发调用

c# - 为什么不尝试{} catch {}在C#中工作?

c# - 基于另一个不同类型的集合创建一个对象集合

c# - 如何将集合的子集传递给 C# 方法?

c# - 在哪里可以找到一套标准的网页设计规则?

java - Java任务中的错误处理

来自文件的 Java 迷宫

c# - 如何在 NHibernate 中映射具有外键关系的两个表?