首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何捕获在ASCX控件(而不是代码隐藏)上引发的异常?

如何捕获在ASCX控件(而不是代码隐藏)上引发的异常?
EN

Stack Overflow用户
提问于 2011-04-14 20:40:17
回答 5查看 5K关注 0票数 2

我有一个很大的ASPX页面,里面有许多ASCX控件。如果控件引发异常,它应该记录该异常并只隐藏它自己。所有其他控件仍应呈现。

如何处理从前端文件( ASCX而不是代码隐藏)引发的单个ASCX的异常?例如:尝试使用<%= MethodThatThrowsANullReferenceException() %>语法引用无效属性的控件。

显然,在Global.asax中使用泛型错误处理程序方法不能解决问题。我需要处理单个控件上的异常。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-04-14 21:58:01

Jim Bolla建议的一种选择是使所有控件从相同的基类继承,并在Render方法中使用Try/Catch。这样就行了。不幸的是,我正在处理的许多控件已经有了不同的基类。

这个解决方案对我很有效:

我在每个用户控件中添加了以下代码(我相信这可以进一步重构以减少重复):

代码语言:javascript
复制
#region Error Handling

public event EventHandler ControlCrashed;
private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

protected override void RenderChildren(HtmlTextWriter writer)
{
    try
    {
        base.RenderChildren(writer);
    }
    catch (Exception exc)
    {
        Logger.Error("Control failed to load. Hiding control. Message: " + exc, exc);
        //Ignore and hide the control.
        this.Visible = false;
        if (ControlCrashed != null)
            ControlCrashed(this, EventArgs.Empty);
    }
}

#endregion

这将捕获任何前端渲染问题。如果父页面希望显示一条漂亮的错误消息,它可以处理ControlCrashed事件。

票数 0
EN

Stack Overflow用户

发布于 2011-04-14 21:42:34

使您的所有UserControls继承自自定义基类,如下所示:

代码语言:javascript
复制
public class CustomUserControl : UserControl
{
    protected override void Render(HtmlTextWriter writer)
    {
        try
        {
            base.Render(writer);
        }
        catch (Exception e)
        {
            writer.Write("Could not load control. Sad face.");
        }
    }
}
票数 4
EN

Stack Overflow用户

发布于 2013-01-08 21:23:29

我尝试了重写Render方法,但这并不涵盖所有的异常。

例如,如果在Page_Init、Load或Render期间抛出某种异常,这将阻止页面呈现。

我们有不同的人处理可以加载到单个页面中的不同模块(控件),但我不负责每个模块的代码质量,所以即使这不是最佳实践,我也需要捕获异常并确定哪个控件加载失败,因为应用程序不会因为一个模块失败而失败。

对于这种如今并不少见的特殊情况,自定义、应用程序或页面错误处理都不会很好地工作。

我想出的解决方案是:

当需要加载到页面(aspx)中时,每个模块(Control.ascx)都包含在一个ModuleShell中,该a将包含一些特定的功能,并负责帮助Page_Error处理正常工作。

此ModuleShell不是尝试捕获失败的子控件的异常,而是在每个生命周期阶段进行监视,如果它能够正确加载的话。

下面是它的一个片段:

代码语言:javascript
复制
    protected void Page_Init(object sender, EventArgs e)
    {
        Modules.CurrentState = _mod;
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        Modules.CurrentState = _mod;
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        Modules.CurrentState = _mod;
    }

模块是用于存储会话变量的静态类。CurrentState是ModuleShell用来记录他们名字的变量。

位于我们得到的唯一aspx中的Page_Error将获得尝试加载的最后一次记录的ModuleShell。由于任何异常都会停止页面呈现,最后一个将其名称记录到主页的ModuleShell,很可能就是无法正确加载的那个。

这是一个草率的解决方案,但对模块开发人员来说是透明的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5663371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档