我有一个很大的ASPX页面,里面有许多ASCX控件。如果控件引发异常,它应该记录该异常并只隐藏它自己。所有其他控件仍应呈现。
如何处理从前端文件( ASCX而不是代码隐藏)引发的单个ASCX的异常?例如:尝试使用<%= MethodThatThrowsANullReferenceException() %>语法引用无效属性的控件。
显然,在Global.asax中使用泛型错误处理程序方法不能解决问题。我需要处理单个控件上的异常。
发布于 2011-04-14 21:58:01
Jim Bolla建议的一种选择是使所有控件从相同的基类继承,并在Render方法中使用Try/Catch。这样就行了。不幸的是,我正在处理的许多控件已经有了不同的基类。
这个解决方案对我很有效:
我在每个用户控件中添加了以下代码(我相信这可以进一步重构以减少重复):
#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事件。
发布于 2011-04-14 21:42:34
使您的所有UserControls继承自自定义基类,如下所示:
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.");
}
}
}发布于 2013-01-08 21:23:29
我尝试了重写Render方法,但这并不涵盖所有的异常。
例如,如果在Page_Init、Load或Render期间抛出某种异常,这将阻止页面呈现。
我们有不同的人处理可以加载到单个页面中的不同模块(控件),但我不负责每个模块的代码质量,所以即使这不是最佳实践,我也需要捕获异常并确定哪个控件加载失败,因为应用程序不会因为一个模块失败而失败。
对于这种如今并不少见的特殊情况,自定义、应用程序或页面错误处理都不会很好地工作。
我想出的解决方案是:
当需要加载到页面(aspx)中时,每个模块(Control.ascx)都包含在一个ModuleShell中,该a将包含一些特定的功能,并负责帮助Page_Error处理正常工作。
此ModuleShell不是尝试捕获失败的子控件的异常,而是在每个生命周期阶段进行监视,如果它能够正确加载的话。
下面是它的一个片段:
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,很可能就是无法正确加载的那个。
这是一个草率的解决方案,但对模块开发人员来说是透明的。
https://stackoverflow.com/questions/5663371
复制相似问题