PDA

Click to See Complete Forum and Search --> : VS 2008 ast.net MVC1 - strange behavior when calling actions.


stlaural
Feb 4th, 2011, 02:01 PM
Ok, this one is one of the strangest bug/behavior I've seen, I can't actually post all my code but will try to explain as well as possible and post only small part of code.

I have 3 actions in one of my controller :


[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Manage(int? id, int? periodID)
{
....
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Manage(ManageTimeSheetViewData viewData, TimeSheetAction? todo)
{
...
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveDraftAjax(ManageTimeSheetViewData viewData)
{
...
}


Basically, the page is a timesheet, users can enter the time they have worked on each project during the week. What I did is I used jQuery and Ajax to automatically save the timesheet each, let's say 3 minutes, this way that page never timesout and if a user edit his timesheet, and close his browser or tab without clicking on the save button, chances are that his timesheet has been saved anyway.

Here is the jQuery/Ajax code that does so :


setInterval(function() {
$('#postForm').ajaxSubmit({
url: 'SaveDraftAjax',
dataType: "json",
success: function(data) {
$("[class=SaveDraftMessage]").remove();
$.each(data.Messages, function(index, value) {

$("[id=SaveDraftResult]").append('<li class="SaveDraftMessage">' + value + '</li>');
});
}
});
}, 180000);


The default action of the form "postForm" is "Manage" but I override it in the ajax call by setting url to "SaveDraftAjax".

Here is the problem: when you enter your timesheet (GET) you can edit values, keep the page open as long as you want and every 3 minutes, the ajax call is called and the "SaveDraftAjax" action is called and everything works fine. at this moment, your address bar shows "http://localhost:60009/TimeSheets/Manage". Now the user decides to click the save button as he wants to make sure everything is saved, which will call the POST action "Manage". this method saves the data, the same way that "SaveDraftAjax" does, but it also sets confirmation messages and then it calls GET "Manage". so the page will be refreshed, showing the confirmation messages, and the address bar now displays "http://localhost:60009/TimeSheets/Manage/94?todo=Save" "94" being my user id in the database and "Save" being the action that was passed to "Manage" action during the POST.

(OK, I didn't code that and I know that there should have been one action for each "todo" possible values instead of passing that value to a single action, but I simply have no time to refactor the whole thing :p)

What happens next, if you stay on that page, is that the Ajax will still be called every 3 minutes, the problem is that now, each time it is called, instead of executing the "SaveDraftAjax" action, the POST "Manage" action is called, which is not what I want, I want "SaveDraftAjax" to be called and executed.

I simply can't figure out WHY? I have a feeling that it might come from the URL that changed in the address bar. I havent worked much with MVC yet so if anyone has a clue about that...

stlaural
Feb 7th, 2011, 12:09 PM
Well, until I can find the exact problem and a solution to it, I simply decided to call SaveDraftAjax from Manage when the "todo" parameter is null. Its a stupid work around but at least it will work.

Krokonoster
Feb 7th, 2011, 11:07 PM
url: 'SaveDraftAjax'
U got a routete defined as such?
Otherwise you should rather call this with controller/action.

Do you look at how things get posted using firebug?

Krokonoster
Feb 7th, 2011, 11:14 PM
url: 'SaveDraftAjax'
U got a routete defined as such?
Otherwise you should rather call this with controller/action.

Do you look at how things get posted using firebug?

stlaural
Feb 8th, 2011, 06:33 AM
I already tried calling it with the Controller/Action syntax but it didn't work. I'll have a look at defining routes and I will also give a try to firebug. I'm pretty sure the problem comes from the routes, what I don't understand is why it works perfectly well until I click the save button that calls the "Manage" action.

Evil_Giraffe
Feb 8th, 2011, 07:30 PM
What does your redirect code in the POST version of Manage look like?

stlaural
Feb 9th, 2011, 06:29 AM
There are two possibilities, if the Cancel button was clicked then we redirect the user to a view named "ViewActions"

return RedirectToAction("ViewActions", "Admin");

Otherwise, error message or confirmation message are set and we return the current view which is named "Manage" and we provide a new viewdata.

return View("Manage", viewData);