我正在动态加载用户控件,将它们添加到Web窗体的Controls集合中。

我想隐藏用户控件,如果它们在渲染时导致未处理的异常。

因此,我尝试 Hook 到每个UserControl的Error事件,但似乎该事件从未像对Page类一样对UserControls触发。

进行了一些谷歌搜索,似乎没有希望。这里有什么想法吗?

最佳答案

mmilic,从your response到我的previous idea ..

无需其他逻辑!重点是,您对所涉及的类不执行任何操作,只需将它们包装在一些实例化泡沫包装中即可! :)

好的,我只是想提出要点,但我想亲自看看这项工作,因此我将一些非常粗糙的代码拼凑在一起,但是这个概念确实存在并且似乎可行。

长期职位的歉意

安全加载器

这基本上就是我提到的“气泡”。它将获取控件HTML,捕获在渲染过程中发生的任何错误。

public class SafeLoader
{
    public static string LoadControl(Control ctl)
    {
        // In terms of what we could do here, its down
        // to you, I will just return some basic HTML saying
        // I screwed up.
        try
        {
            // Get the Controls HTML (which may throw)
            // And store it in our own writer away from the
            // actual Live page.
            StringWriter writer = new StringWriter();
            HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
            ctl.RenderControl(htmlWriter);

            return writer.GetStringBuilder().ToString();
        }
        catch (Exception)
        {
            string ctlType = ctl.GetType().Name;
            return "<span style=\"color: red; font-weight:bold; font-size: smaller;\">" +
                "Rob + Controls = FAIL (" +
                ctlType + " rendering failed) Sad face :(</span>";
        }
    }
}

和一些控件

好的,我只是在这里 mock 了两个控件,一个控件将抛出另一个控件将渲染为垃圾。指向这里,我不要胡扯。这些将替换为您的自定义控件。

不良控制
public class BadControl : WebControl
{
    protected override void Render(HtmlTextWriter writer)
    {
        throw new ApplicationException("Rob can't program controls");
    }
}

良好控制
public class GoodControl : WebControl
{
    protected override void Render(HtmlTextWriter writer)
    {
        writer.Write("<b>Holy crap this control works</b>");
    }
}

这页纸

好的,让我们看一下“测试”页面。在这里,我只是实例化控件,获取它们的html并输出它,然后我将介绍有关设计人员支持的想法。

页面代码隐藏
    protected void Page_Load(object sender, EventArgs e)
    {
        // Create some controls (BadControl will throw)
        string goodHtml = SafeLoader.LoadControl(new BadControl());
        Response.Write(goodHtml);

        string badHtml = SafeLoader.LoadControl(new GoodControl());
        Response.Write(badHtml);
    }

思想

好的,我知道您在想什么,“这些控件以编程方式实例化,那么对设计师的支持又如何呢?我花了很多时间才使这些控件对设计师来说很好,现在您正在弄乱我的mojo”。

好的,所以我还没有真正测试过它(可能会在一分钟内完成!),但是这里的想法是覆盖页面的CreateChildControls方法,并获取表单上添加的每个控件的实例,并通过SafeLoader运行它。如果代码通过,则可以按正常方式将其添加到Controls集合中,如果没有通过,则可以创建错误的文字或其他内容,由我的 friend 决定。

最后..

再次,对冗长的帖子表示抱歉,但我想在此处获取代码,以便我们进行讨论:)
我希望这有助于证明我的想法:)

更新

通过将控件插入设计器中并使用此方法覆盖CreateChildControls方法进行测试,效果很好,可能需要进行一些清理才能使外观看起来更好,但我将留给您;)
protected override void CreateChildControls()
{
    // Pass each control through the Loader to check
    // its not lame
    foreach (Control ctl in Controls)
    {
        string s = SafeLoader.LoadControl(ctl);
        // If its bad, smack it downnnn!
        if (s == string.Empty)
        {
            ctl.Visible = false; // Prevent Rendering
            string ctlType = ctl.GetType().Name;
            Response.Write("<b>Problem Occurred Rendering " +
                ctlType + " '" + ctl.ID + "'.</b>");
        }
    }
}

享受!

关于asp.net - 捕获ASP.NET UserControls中未处理的异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10793/

10-09 08:19