2010-07-31 24 views
7

我爲我的所有表單使用了post-redirect-get模式,但現在需要添加AJAX功能來改善用戶體驗。我最初的想法是,兩者不會混合。PRG模式是否與AJAX表單文章不兼容?

在PRG方案中,如果存在驗證錯誤,我會將我的發佈操作重定向回我的獲取操作,否則將重定向到我的成功獲取操作。

在AJAX場景中,我需要以任何方式返回部分視圖。更典型的是,我會先檢查它是否是AJAX請求。如果是這樣,返回部分視圖,否則返回視圖。

任何想法或建議?

回答

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); 
} 

儘管如此,有時候我會懷疑我們可能做得有點錯誤

+0

您可以將if ajax ...邏輯抽象成基類中的AjaxView方法以消除混亂。您的方法的主要問題是您從POST操作返回視圖,因此在驗證失敗的情況下它不是PRG。我使用模型狀態的導出和導入重定向回原來的GET操作。主要問題是FireFox不保留重定向之間的ajax標誌,所以在我的GET操作中,IsAjaxRequest爲false。我現在必須用另一個將標誌保存到tempdata的動作過濾器來解決這個問題。雖然不是很優雅。 – 2010-09-03 15:07:29

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方便的嘗試它。

+2

關於PRG避免重複提交的目的的好處,這與AJAX無關 – Acyra 2012-03-16 13:41:57