Can I retrieve the exception, querystring, form variables after a
redirect to an
error page specified in the web.config?
Not directly.
I need to create error logging.
I know about Application_Error handler in global.asax, but it does
not seem to be suited for me.
Why not, the need to get all of the form elements? If so, see below.
Server.GetLastError().GetBaseException() does not work in error.aspx.
No, it will not, as the error has already been consumed in the event,
even if you have no application error event handler.
<customErrors mode="On" defaultRedirect="Error.aspx">
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
There is nothing easy about this. You have two choices:
1. Figure out where the potential error-ridden code is and pull values
prior to this point.
2. use the Application_Error to pull all form elements (and perhaps
other Request elements
Sample code:
void Application_Error(object sender, EventArgs e)
{
// Get page that threw the error
HttpContext context = HttpContext.Current;
string url = context.Request.Url.ToString();
Exception exception = Server.GetLastError();
//Log ex
if (exception.InnerException != null)
{
Exception inner = exception.InnerException;
//Log inner exception
}
Exception baseException = exception.GetBaseException();
//Log base
//Get context to get page elements
HttpRequest request = context.Request;
//Pulls form elements
foreach (string key in Request.Form.AllKeys)
{
string value = Request.Form[key];
//Log the value here
}
}
This is fine for first time encounters with errors, but a persistent
problem using this route is very sloppy.
Unwinding the exception object can be done like so:
private void LogException(Exception ex)
{
string type = ex.GetType().ToString();
string message = ex.Message;
string stackTrace = ex.StackTrace;
string targetSite = ex.TargetSite;
//May also want data (rarely, but possible)
//Log elements here
}
And, if you want to handle the inner exception without explicitly coding
a separate section, you can unwind a whole stack of exceptions like so:
private void LogException(Exception ex, int indent)
{
string type = ex.GetType().ToString();
string message = ex.Message;
string stackTrace = ex.StackTrace;
string targetSite = ex.TargetSite;
//May also want data (rarely, but possible)
//Log using indent so you cascade the exceptions
// to more easily figure exception nesting
if (ex.InnerException != null)
{
LogException(ex, indent + 4);
}
}
The initial call is then:
LogException(ex, 0);
Peace and Grace,