PRG模式是否与AJAX表单帖子不兼容?

时间:2010-07-31 15:44:01

标签: asp.net-mvc ajax post-redirect-get

我正在为所有表单使用post-redirect-get模式,但现在需要添加AJAX功能以改善用户体验。我最初的想法是两者不混合。

在PRG场景中,如果出现验证错误,我会进行后期操作,然后重定向回我的get操作,否则重定向到我的成功获取操作。

在AJAX场景中,我需要以任一方式返回局部视图。更典型的是,我会首先检查它是否是一个AJAX请求。如果是,则返回局部视图,否则返回视图。

有任何想法或建议吗?

2 个答案:

答案 0 :(得分:4)

我们在我们的应用中使用Post-Redirect-Get。这是我们所做的事情的本质,它取决于Request.IsAjaxRequest()方法并将您的视图拆分为.aspx,每个都托管.ascx,以便可以同步和异步(即通过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);
        }
    }
}

我们在此处略有变化,我们专门捕获RulesException(来自xVal,以便将模型验证错误与其他“更严重”的异常区别对待。

catch (RulesException re)
{
    re.AddModelStateErrors(ModelState, "");

    return View(foo);
}

尽管如此,有时候我会怀疑我们可能会做的有些不对。

答案 1 :(得分:3)

嗯,PRG的部分原因是为了避免“你想重新提交表格吗?”对话。 AJAX通常没有这个问题,因为你不是真的做'POST'(你,但你抓住了我的漂移)。

无论如何,Rails支持你想要做的事情,我认为将它粗略地翻译成ASP.NET MVC并不是那么粗略。

首先,您可以告诉客户端JavaScript将AJAX发送为text/javascript。使用jQuery:

jQuery.ajaxSetup({
    'beforeSend': function(xhr) { xhr.setRequestHeader("Accept", "text/javascript"); }
});

在运行AJAX之前把它放到某处。这将影响所有其他AJAX调用,但除非您在后端查找,否则不应该无意中执行任何操作。

然后,在您的控制器中,查找text/javascript标头并做出相应的响应。查看此SO question,其中引用了this article。希望我能提供更多信息,但我现在没有VS方便试试。