Friday, May 28, 2010

Handling Login Redirects When Mixing ASP.NET MVC 2 and WebForms

I've been migrating parts of GridRoom over to the ASP.NET MVC 2 framework as a precursor to implementing more advanced Ajax support (sans WebForms and ASP.NET AJAX).

One of the challenges to making WebForms and MVC coexist is handling redirects to the login page when making Ajax requests. This can happen when a user's session times out or if they log out in another browser window.

When this occurs the server returns a 302 temporary redirect to the login page, but the redirect status code is not exposed via the JavaScript XMLHttpRequest object. Instead, you get back a 200 OK response that happens to include the entire login page rather than the snippet of Html or Json payload you were expecting.

The simplest way I've found to handle this scenario (while retaining the existing WebForms login page) is to check for the presence of the ASP.NET MVC version header in every Ajax response. If the header doesn't exist the current document is simply reloaded to force a top-level redirect to the login page.

To make this work with jQuery, simply register a callback with the jQuery.ajaxSuccess() event and check for the "X-AspNetMvc-Version" response header:

   1: $(document).ajaxSuccess(function(event, XMLHttpRequest, ajaxOptions) {
   2:    // if request returns non MVC page reload because this means the user 
   3:    // session has expired
   4:    var mvcHeaderName = "X-AspNetMvc-Version";
   5:    var mvcHeaderValue = XMLHttpRequest.getResponseHeader(mvcHeaderName);
   7:    if (!mvcHeaderValue) {
   8:        location.reload();
   9:    }
  10: );

The page reload may cause some JavaScript errors (depending on what you're doing with the Ajax response), but in most cases where debugging is off the user will never see these.

No comments:

Header photo courtesy of: / CC BY-NC 2.0