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);
   6:  
   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.

Tuesday, May 11, 2010

Preventing Multiple Form Submits In ASP.NET

Last year when I started working on the GridRoom Web site I spent some time researching the current best-practices for preventing multiple form submits in ASP.NET. (It was the first site I'd built from scratch using .NET, and I wasn't particularly fond of the architecture of existing .NET sites I had worked on.)

There are many options for preventing multiple submits, some of them quite complex and convoluted. But for most sites where the goal is simply to prevent users from accidentally clicking a submit button more than once the solution is very simple. Just override the OnLoad() method of your master page like this:

   1: protected override void OnLoad(EventArgs e)
   2: {
   3:     base.OnLoad(e);
   4:  
   5:     // prevents form from being submitted multiple times in MOST cases
   6:     // programatic client-side calls to __doPostBack() can bypass this
   7:     Page.ClientScript.RegisterOnSubmitStatement(GetType(), "ServerForm",
   8:                                                 "if (this.submitted) return false; this.submitted = true; return true;");
   9: }

This registers a script block with the client-side form's OnSubmit event that prevents the form from being submitted multiple times, regardless of how many times the user clicks (or how many submit buttons are on the form).

This solution does not prevent users from intentionally submitting the same form multiple times. (This could be done programmatically, by refreshing the post-submit page, or by hitting the back button and resubmitting.)

You'll need to handle intentional re-submits on a case-by-case basis in your business logic. But if you're looking for a very simple solution that simply prevents inexperienced users from being confused by unexpected errors or duplicate data this will do the trick.

Monday, May 10, 2010

Restore Your Missing Blogger Comments

I moved this blog to a custom domain about two months ago. Blogger makes the process very simple if you already own your own domain. I was up and running at blog.coditate.com after just a few clicks in the Blogger dashboard, and adding a new CNAME record for this domain.

A short time later I realized all the comments were missing from this blog. Apparently this has been quite a problem for months and based on the hundreds of unanswered complaints in the Blogger help forum, Google hasn't been very responsive or helpful in explaining why this happens or how to fix it.

Following the advice on this thread, I switched back to my old blogger-hosted address and the old comments reappeared. However, all new comments added since the domain switch had now disappeared. I switched back to my custom domain. Now both the old and new comments were gone!

Finally, after a couple more switches between my custom domain and blogger-address, all comments--both old and new--reappeared at once and seem to be sticking around. But the unreliability and lack of support from Google are not exactly confidence inspiring. In fact, it's downright scary when I think about how much of my important data is spread across Google's free services.

 
Header photo courtesy of: http://www.flickr.com/photos/tmartin/ / CC BY-NC 2.0