1

Short version: What's the best way to stay on the same page to run a second AJAX call after an AJAX ASP.NET Membership Authentication response is received?

Long version: Imagine a web-based Paint program built in ASP.NET MVC. The user paints a picture, during which time the user's session has timed out. The user hits "save" and is prompted with an AJAX dialog, "Your session has timed out. Please enter your credentials below." (See jQuery Forms Authentication with ASP.NET MVC for how to do AJAX authentication.) After entering valid credentials, the user is re-authenticated.

Typically, at this point, users are redirected to returnUrl, as is evident by MVC's default login method signature:

public ActionResult LogOn(LogOnModel model, string returnUrl)

However, in this case, I would like to stay on the same page and instead make an AJAX call to my handler, SaveArt(), which will write the user's work to the database. I could hijack returnUrl to have it contain the name of the subsequent Javascript function I'd like to call, but the only way I can think to execute it from the client is with the dreaded eval, which does not at all seem secure. Is there another way to fully AJAXify this process? What are the dangers of using eval here, to run a function whose name is returned by the server?

Community
  • 1
  • 1
ChessWhiz
  • 4,656
  • 3
  • 26
  • 40

2 Answers2

3

If you are using an an Ajax request to do the login, you can modify the accountcontroller to detect it using Request.IsAjaxRequest() (or one of several other methods) and return a json object with the result of the login request instead of a redirect. From there you just need to handle that object to display the result.

--Amended answer--

What you need to do is check the responsecode from the ajax call before you continue on in whatever you wanted to do.. jQuery 1.5's ajax() method allows you to do this:

$.ajax({
  statusCode: {404: function() {
    alert('page not found');
  }
});

In your case, provided you are indeed using the [Authorize] attribute, you have to handle the 401 status code. There is likely where you would show your login dialog. When you instantiate your login dialog pass in a closure that calls the SaveArt() function again.

Hopefully this is more helpful to you.

Chad Ruppert
  • 3,650
  • 1
  • 19
  • 19
  • Read the question carefully. I already know how to "handle that object and display the result." What I'm not sure about is how to call another JS function after the result. Basically, the `Save` click handler should login via AJAX if needed, then call a second AJAX method to save the art. How will the login response handler know to call `Save`, when that function name is known only at the time of the original click? – ChessWhiz Feb 07 '11 at 05:14
  • pardon me good sir, but "The user hits "save" and is prompted with an AJAX dialog" indicated to me that you were already beyond the point of dealing with the result of lost session for an action tagged as [Authorized]. I did indeed misread that that solution is what you were looking for. I instead only gave you the latter half of what you wanted. Amending answer. – Chad Ruppert Feb 07 '11 at 05:50
  • That is useful, thanks. However, this solution requires a custom errorhandler on each AJAX request, of which `Save` is just one. Is there a way to refactor the preauth into one function call, as in `CallWithAuthentication(Save)`? This is a helper that authenticates if needed, then executes whatever function pointer it receives as a parameter. The issue with this is that the login success handler has trouble accessing the `Save` function pointer parameter unless the server returns it. – ChessWhiz Feb 07 '11 at 06:17
  • 1
    Yes, you can do something just like that. You should not have trouble accessing the save call unless you are doing crossdomain stuff. Modify your method call to look more like CallWithAuthentication(function(){Save();}); ie a closure. – Chad Ruppert Feb 07 '11 at 14:27
2

"Chad Ruppert" answer is correct. But if you do not understand please follow the below alogrithm.

1) declare a javascript function that make AJAX call for authentication with the paramter i) username ii) password iii) callback function

2) In the response of AJAX call probably you know the result of the validation whether user/psd is correct or not.

3) If the validation got thru then call the callback function (Callback function is notting but your SAVE())

Madhu
  • 5,686
  • 9
  • 37
  • 53