且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在ASP.NET UserControls中捕获未处理的异常

更新时间:2023-02-15 13:00:16

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,捕获在渲染期间发生的任何错误。 p>

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



一些控件..



Ok我只是嘲笑这里的两个控件,一个会抛出另一个会渲染垃圾,指向这里,我不会废弃,这些将被您的自定义控件替换。

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



GoodControl



GoodControl

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



想法



好吧,我知道你在想什么,这些控件是以程序方式实例化的,设计师的支持是什么呢?我花了很多时间让这些控件很好的设计师,现在你正在搞乱我的mojo。

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".

OK,所以我没有真正测试过这个(可能会在一分钟内完成),但是这里的想法是覆盖该页面的CreateChildControls方法,并将每个控件的实例添加到形成并通过SafeLoader运行它。如果代码通过,您可以将它添加到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>");
        }
    }
}

享受!