views:

37

answers:

2

Hello,

I have error handling in Application_Error event of globals.asax file. Inside this event, I'm using Response.Redirect(~errorview.aspx) method, for redirection to site which is able to handle errors in user friendly way.

Everything works fine, unless exception is rising in Application_Start event. When error occurs there, my application gets trapped in infinite loop with the Application_Error method hit repeatedly. What is more, the page I'm redirecting to never gets hit. Changing Response.Redirect(~errorview.aspx) method to Response.Redirect(~errorview.aspx, false) changes nothing.

The good news is, when Response.Redirect(~errorview.aspx) has been replaced with Server.Transfer(~errorview.aspx), errorview.aspx page succesfully gets hit.

The side effect now is not loading CSS, and errorview.aspx page looks ugly. What is more, the CSS is not loaded only when exception occurs in Application_Start event. Exceptions thrown from any other place don't make the CSS mess.

How I can handle this problem in correct way, and why the CSS is missing in the one particular situation ? What is the appropriate way of handling errors in my case ?

UPDATE

For CSS loading, I'm using this:

<link href="~/Css/Layout/style.css" type="text/css" rel="stylesheet" 
      runat="server" ID="_uid" />

error page I'm transfering from: http://localhost/APP/Pages/Module/Pages/ErrorView.aspx

css folder path: http://localhost/APP/Pages/Module/CSS/Layout/style.css

Thanks for any clues in advance. Regards.

A: 

Response.Redirect simulate a HTTP 302 code : Object moved. The browser will do a second and real request.

Server.Transfert simply transfert the execution to the second page. It's still the same and initial request. If you wrote something in the response buffer in the first page before transfert, you'll got the two page ouput appended as result.

About your CSS thing, I guess you are using a relative path which mean relative to the first page when using Server.transfert. If not, post some code :)

About error handling, Application_Start should never throw an exception and Application_Error should handle its own exception.

About loop, depending of the case, you can avoid page loop by sending a HTTP 500 code to indicate to the client that the application context is in a mess ;) ie. in the OnError event of your custom error page for example.

JoeBilly
Hey, CSS path is ok - page normally works with Server.Transfer but CSS is not loaded only when Server.Transfer is a result of exception occurance in Application_start event. When it comes to Application_start, I have a lot of type initializations in IoC container there, and sometimes when some type mapping is missing, or there are some problems with nhibernate context creation, etc exception occurs, so I need to handle that.
Jarek Waliszko
A: 

If you're getting exceptions during Application_Start, you have bigger problems than trying to get CSS to load in the error page. Application_Start is intended as a bootstrapper for the Web site to initialize everything. If you can't successfully initialize the application, you probably won't be able to service any requests. (You shouldn't be publishing an application to a production environment when it is known to have exceptions in the Application_Start anyway.)

Ultimately, what Server.Transfer is doing is simply switching from processing the current path to processing the new path. The request context is not modified, so any relative references in the new path are relative to the original request. If an exception happens in Application_Start, there is no original request. (Requests aren't handled by Application_Start. A request can cause Application_Start to be invoked, but it won't know anything about the request.) That's probably why Server.Transfer from an Application_Start exception doesn't load the CSS - there's no original request context.

Also, it's generally a better idea to have a static html-only error page. If there's an error caused by some ASP.NET processing in IIS, then it's likely that an error page that is also processed by the ASP.NET will suffer the same error, possibly causing an infinite loop (the error page redirects to the error page because there was an error - lather, rinse, repeat). (This is the infinite loop situation that you experienced.) Eventually, good browsers will notice this and stop the loop, but you still have the runaway request cycle. If you use a static html-only page, then you prevent ASP.NET from ever attempting to process the request. (It's usually cleaner, too, as you should have a very simple, straightforward error page that displays to the visitor and have all the error trapping and notifications handled behind the scenes.)

TLS
I wanted to add a little bit to this - something that can cause confusion at first glance. When you use Server.Transfer, it doesn't start a new Response. If you've written anything to the Response (for example, if the error occurs midway through generating the output for the page), then you'll get your new page rendered within that context. If you want to make sure that your error page is the only thing rendered to the browser, you'll want to call Response.Clear *before* calling Server.Transfer. (One of the other answers below mentions this briefly.)
TLS