在 ASP.NET 用户控件中捕获未处理的异常 [英] Catching unhandled exceptions in ASP.NET UserControls

查看:12
本文介绍了在 ASP.NET 用户控件中捕获未处理的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在动态加载用户控件,并将它们添加到 Web 表单的 Controls 集合中.

I'm dynamically loading user controls adding them to the Controls collection of the web form.

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

I'd like to hide user controls if they cause a unhandled exception while rendering.

所以,我尝试连接到每个 UserControl 的 Error 事件,但似乎该事件永远不会像对 Page 类那样为 UserControls 触发.

So, I tried hooking to the Error event of each UserControl but it seems that this event never fires for the UserControls as it does for Page class.

在谷歌上搜索了一下,似乎没有希望.这里有什么想法吗?

Did some googling around and it doesn't seem promising. Any ideas here?

推荐答案

mmilic,继 您对我的之前的想法的回复..

mmilic, following on from your response to my previous idea..

不需要额外的逻辑!这就是重点,您对有问题的类什么都不做,只是将它们包装在一些实例化气泡包装中!:)

No additional logic required! That's the point, your doing nothing to the classes in question, just wrapping them in some instantiation bubble-wrap! :)

好的,我打算只说要点,但我想亲眼看看这项工作,所以我拼凑了一些非常粗略的代码,但概念就在那里,而且似乎有效.

OK, I was going to just bullet point but I wanted to see this work for myself, so I cobbled together some very rough code but the concept is there and it seems to work.

为长篇道歉

这基本上就是我提到的气泡".它将获取控件 HTML,捕捉渲染期间发生的任何错误.

This will basically be the "bubble" I mentioned.. It will get the controls HTML, catching any errors that occur during Rendering.

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>";
        }
    }
}

还有一些控件..

好的,我只是在这里模拟了两个控件,一个会抛出另一个会呈现垃圾.点这里,我不废话.这些将替换为您的自定义控件..

And Some Controls..

Ok I just mocked together two controls here, one will throw the other will render junk. Point here, I don't give a crap. These will be replaced with your custom controls..

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 并输出它,然后我会思考设计器支持等.

The Page

OK, so lets look at the "test" page.. Here I simply instantiate the controls, grab their html and output it, I will follow with thoughts on designer support etc..

    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);
    }

想法

好的,我知道你在想什么,这些控件是以编程方式实例化的,设计师支持呢?我花了好几个小时让这些控件对设计师来说很好,现在你在搞乱我的魔力".

Thoughts

OK, I know what you are thinking, "these controls are instantiated programatically, what about designer support? I spent freaking hours getting these controls nice for the designer, now you're messing with my mojo".

好的,所以我还没有真正测试过这个(可能会在几分钟内完成!)但这里的想法是覆盖页面的 CreateChildControls 方法,并获取添加到表单上的每个控件的实例并运行它安全加载器.如果代码通过了,你可以像往常一样将它添加到 Controls 集合中,如果没有,那么你可以创建错误的文字或其他东西,这取决于你我的朋友.

OK, so I havent really tested this yet (probably will do in a min!) but the idea here is to override the CreateChildControls method for the page, and take the instance of each control added on the form and run it through the SafeLoader. If the code passes, you can add it to the Controls collection as normal, if not, then you can create erroneous literals or something, up to you my friend.

再次抱歉,很抱歉这篇文章很长,但我想在这里获取代码,以便我们讨论这个问题 :)我希望这有助于证明我的想法:)

Again, sorry for the long post, but I wanted to get the code here so we can discuss this :) I hope this helps demonstrate my idea :)

通过在设计器上插入一个控件并用它覆盖 CreateChildControls 方法进行测试,工作正常,可能需要一些清理以使事情看起来更好,但我会把它留给你;)

Tested by chucking a control in on the designer and overriding the CreateChildControls method with this, works fine, may need some clean up to make things better looking, but I'll leave that to you ;)

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 用户控件中捕获未处理的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆