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 wh
I used @Keith's approach, but the problem is that the control is rendered up until the Exception is thrown, potentially resulting in open HTML tags. I'm also rendering the exception information in the Control if in Debug mode.
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
try
{
// Render the module to a local a temporary writer so that if an Exception occurs
// the control is not halfway rendered - "it is all or nothing" proposition
System.IO.StringWriter sw = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);
base.Render(htw);
// We made it! Copy the Control Render over
writer.Write(sw.GetStringBuilder().ToString());
}
catch (System.Exception ex)
{
string message = string.Format("Error Rendering Control {0}\n", ID);
Log.Error(message, ex);
if (Page.IsDebug)
writer.Write(string.Format("{0}<br>Exception:<br><pre>{1}\n{2}</pre>", message, ex.Message, ex.StackTrace));
}
}
This is an interesting problem.. I am still pretty fresh when it comes to custom controls etc, but here are my thoughts (feel free to comment/correct people!).. (I am kinda thinking/writing out loud here!)
Just my thoughts, flame away! :D ;)
Global.asax and Application_Error?
http://www.15seconds.com/issue/030102.htm
Or the Page_Error Event on an individual Page only:
http://support.microsoft.com/kb/306355
void Page_Load(object sender, System.EventArgs e)
{
throw(new ArgumentNullException());
}
public void Page_Error(object sender,EventArgs e)
{
Exception objErr = Server.GetLastError().GetBaseException();
string err = "<b>Error Caught in Page_Error event</b><hr><br>" +
"<br><b>Error in: </b>" + Request.Url.ToString() +
"<br><b>Error Message: </b>" + objErr.Message.ToString()+
"<br><b>Stack Trace:</b><br>" +
objErr.StackTrace.ToString();
Response.Write(err.ToString());
Server.ClearError();
}
Also, Karl Seguin (Hi Karl!) had a Post on using HttpHandler instead:
http://codebetter.com/blogs/karlseguin/archive/2006/06/12/146356.aspx
(Not sure what the permission to reproduce it, but if you want to write up an answer, you got my Upvote ☺)
Depending on where your errors are occurring you can do something like...
public abstract class SilentErrorControl : UserControl
{
protected override void Render( HtmlTextWriter writer )
{
//call the base's render method, but with a try catch
try { base.Render( writer ); }
catch ( Exception ex ) { /*do nothing*/ }
}
}
Then inherit SilentErrorControl instead of UserControl.
I am not sure I understand your response.. How are you loading your controls and adding them to your controls collection?
That was the whole point of the bit added in the "Update" section.. You have the flexibility to use the SafeLoader wherever you please.
I am not sure why you feel you don't have access/control over the Html? The goal of the SafeLoader is that you dont care what the html is, you simply try and "output" the control (within the "bubble") and determine if it loads OK in its current state.
If it does (i.e. the html is returned) then you can do what you like with it, output the html, add the control to the controls collection, whatever!
If not, then again, you can do what you like, render an error message, throw a custom exception.. The choice is yours!
I hope this helps clarify things for you, if not, then please shout :)
How about adding a new sub-class of UserControl that error-handles its render and load methods (so that they hide as you wish) and then inheriting from that for your user controls?