shearichard
shearichard

Reputation: 1105

Handling Request Validation 'silently'

I'm trying to override the onError event handler of a web form to allow "A potentially dangerous Request.Form value was detected from the client" type errors to be handled within the form rather than ending up at the application level error handler.

I found some sample code like this :

   protected override void OnError(EventArgs e)
{
    // At this point we have information about the error
    HttpContext ctx = HttpContext.Current;

    Exception exception = ctx.Server.GetLastError();

    string errorInfo =
       "<br>Offending URL: " + ctx.Request.Url.ToString() +
       "<br>Source: " + exception.Source +
       "<br>Message: " + exception.Message +
       "<br>Stack trace: " + exception.StackTrace;

    ctx.Response.Write(errorInfo);

    // --------------------------------------------------
    // To let the page finish running we clear the error
    // --------------------------------------------------
    ctx.Server.ClearError();

    base.OnError(e);

}

Which satisfactorily catches the error and writes an error message out to the screen but what I really want to do is to be aware of the error when Page_Load fires and so be able to display a 'normal' error message on the webform.

I'm sure there's a good way to do this but I don't know it ! Suggestions ?

(BTW for various reason I don't want to turn off the checking at either form or app level and neither do I wish to rely on Javascript - thanks)

Upvotes: 4

Views: 4252

Answers (3)

Keltex
Keltex

Reputation: 26436

You actually can catch the error at the page level, but it will kill the page lifecycle. So you have to use a trick to get around it. Example:

public override void ProcessRequest(HttpContext context)
{
  try
  {
    base.ProcessRequest(context);
  }
  catch(HttpRequestValidationException ex)
  {
      context.Response.Redirect("HandleValidationError.aspx");
  }
}

HandleValidationError.aspx can be anything, including a redirection back to the same page (perhaps with a querystring with information regarding the error, e.g. "ContactForm.aspx?error=Invalid+Request")

Upvotes: 4

davogones
davogones

Reputation: 7399

I think I understand what you want to do, but I'm afraid it might be impossible. When your ASP.NET page performs a postback, a new thread is created on the server to handle the request. Before your page lifecycle even has a chance to begin, the offending XSS is found and an exception is thrown. Once this exception is thrown, you are "evicted" from the ASP.NET page lifecycle and there is no way to re-enter it. At this point, the only thing you can do on the client side is output the error, or redirect to an error page.

What you seem to want to do is catch the exception, write it out somewhere on the page, and continue with the ASP.NET page lifecycle (i.e. restoring the control tree, restoring viewstate, invoking event handlers, etc). The problem is once an unhandled exception is thrown you no longer have access to the ASP.NET page lifecycle. In this particular case, there is nowhere to put a try/catch block because the exception is thrown internally from the ASP.NET lifecycle before your own code is called.

I know you said you don't want to rely on Javascript, but in this case I think using Javascript is the only way to get the behavior you want. You can still keep server-side validation, just in case your users disable Javascript or type some input that your Javascript doesn't handle.

Upvotes: 1

Jason
Jason

Reputation: 15931

I don't think you'll be able to handle the error in the Page_load event. In the ASP.NET Page Life cycle validation events occur after the page loads.

Maybe you can add a hidden div (<asp:Panel Visible=false ...) that contains your "normal error message". if the OnError event fires display the error message div.

jason

Upvotes: 0

Related Questions