Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在页面生命周期中的Render()之前发生的错误重写YSOD,然后将异常内容作为该控件的HTML注释写入_C#_Asp.net_Error Handling_Sitecore - Fatal编程技术网

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

C# 在页面生命周期中的Render()之前发生的错误重写YSOD,然后将异常内容作为该控件的HTML注释写入,c#,asp.net,error-handling,sitecore,C#,Asp.net,Error Handling,Sitecore,我试图找出一种方法来捕获页面生命周期中Render()方法之前发生的特定类型的所有异常,存储它们并绕过YSOD错误处理程序。然后在覆盖Render()时执行以下操作: protected override void Render(HtmlTextWriter writer) { if(ReqObjectException != null) { base.Render(writer); } else { Log.Error("

我试图找出一种方法来捕获页面生命周期中
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("-->");
    }
}
受保护的覆盖无效渲染(HtmlTextWriter)
{
if(ReqObjectException!=null)
{
base.Render(writer);
}
其他的
{
Log.Error(“基本控件中缺少所需对象”,ReqObjectException,this);
writer.WriteLine(“”);
}
}
这里的想法是,我有一些添加到页面中的动态控件,它们偶尔需要一些与之关联的数据。现在,如果内容作者忘记附加相关的数据,他们会得到一个YSOD,然后发疯。
这里的想法是页面的其余部分继续工作,并且有一个日志条目和一个指向问题的HTML注释。也许我会创建一些警告对话框,让他们知道缺少了一些东西。

多亏了nsgocev的MVC实现,这让我走上了正确的道路

对于Web表单,相同类型的东西不起作用。幸运的是,我们所有的子布局并没有在pageinit或pageload中直接执行它们的逻辑。基准子平面布置有以下方法:

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()

如果页面_Init或base.Render()中存在异常,则执行HandleRenderingException()

publicstaticvoidhandlerenderingexception(TextWriter编写器、异常ex、string baseTypeName、对象所有者)
{
日志错误(“呈现错误”,例如,所有者);
if(Context.PageMode.IsNormal)
{
writer.WriteLine(“”);
}
其他的
{
writer.WriteLine(“”);
writer.WriteLine(“[您的评论或序列化异常]”);
writer.WriteLine(“”);
}
HttpContext.Current.Server.ClearError();
}

这样,如果内容作者添加了一个损坏的控件,他们将在页面编辑器/预览模式下收到一条有用的消息。

如果您使用的是ASP.NET MVC,您通常会在Global.asax中的Application_Error()方法中执行类似操作。这也适用于Sitecore中的单个渲染。我现在不在MVC中工作,但我最终会在MVC中工作,因此相同类型的功能在那里会很有用。对于Sitecore MVC,Charlie Tourano有一篇关于如何实现这种处理的博客。我想这会有帮助:)
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();
    }
}
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();
}