I am using the post-redirect-get pattern for all my forms, but开发者_开发技巧 now need to add AJAX functionality to improve the user experience. My initial thoughts are that the two do not mix.
In the PRG scenario, I would have my post action that would then either redirect back to my get action if there is a validation error, or redirect to my success get action otherwise.
In the AJAX scenario, I need to return a partial view either way. More typically, I would check to see if it is an AJAX request first. If so, return the partial view, else return the view.
Any thoughts or suggestions?
We use Post-Redirect-Get in our app. Here's the essence of what we do, which hinges around the Request.IsAjaxRequest()
method and splitting your views into .aspx each of which host an .ascx so that each can action can be called both synchronously and asynchronously (i.e. via Ajax).
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Foo foo)
{
try
{
// Save the changes to the data store
unitOfWork.Foos.Attach(foo);
unitOfWork.Commit();
if (Request.IsAjaxRequest())
{
// The name of the view for Ajax calls will most likely be different to the normal view name
return PartialView("EditSuccessAsync");
}
else
{
return RedirectToAction("EditSuccess");
}
}
catch (Exception e)
{
if (Request.IsAjaxRequest())
{
// Here you probably want to return part of the normal Edit View
return PartialView("EditForm", foo);
}
else
{
return View(foo);
}
}
}
We have a slight variant on this as well where we specifically catch RulesException
's (from the xVal in order to treat model validation errors differently to other 'more serious' exceptions.
catch (RulesException re)
{
re.AddModelStateErrors(ModelState, "");
return View(foo);
}
Saying all that though, sometimes I get a sneaking suspicion that we might be doing it slightly wrong.
Well, part of the reason for PRG is to avoid the "Do you want to resubmit the form?" dialog. AJAX typically doesn't have this problem, since you aren't really doing a 'POST' (you are, but you catch my drift).
Anyways, Rails supports what you'd want to do, and I don't think it would be that rough translating it to ASP.NET MVC.
First, you can tell your client side JavaScript to send AJAX as text/javascript
. Using jQuery:
jQuery.ajaxSetup({
'beforeSend': function(xhr) { xhr.setRequestHeader("Accept", "text/javascript"); }
});
Put that somewhere before the AJAX is run. This will affect all other AJAX calls, but shouldn't do anything unintended unless you're looking for it on the backend.
Then, in your controller, look for the text/javascript
header and respond accordingly. Check out this SO question, which references this article. Wish I could give more info, but I don't have VS handy to try it out right now.
精彩评论