2012-05-17 43 views
1

我有一個帶有Index方法的控制器,它有幾個可選參數用於過濾返回到視圖的結果。MVC3:帶搜索過濾器的PRG模式行動方法

public ActionResult Index(string searchString, string location, string status) { 
    ... 

product = repository.GetProducts(string searchString, string location, string status); 

return View(product); 
} 

我想實現像下面的PRG模式,但我不知道如何去做。

[HttpPost] 
public ActionResult Index(ViewModel model) { 
    ... 
    if (ModelState.IsValid) { 
     product = repository.GetProducts(model); 
    return RedirectToAction(); // Not sure how to handle the redirect 
    } 
return View(model); 
} 

我的理解是,你不應該使用這個模式,如果:

  • 你並不需要使用這種模式,除非你有實際存儲一些數據(我不是)
  • 你不會使用這種模式來避免在刷新頁面時出現「確定要重新提交」消息(有罪)

我應該試圖使用這種模式嗎?如果是這樣,我該怎麼辦呢?

謝謝!

+0

我肯定會使用這個模式,以避免對即對話「你不會使用這種模式避免了‘你確定你想要的’刷新頁面時(犯)從IE消息」,以重新提交其一般不鼓勵最終用戶,他們通常不知道該怎麼做「我點擊取消嗎?我點擊好嗎?啊!太多的決定!!」 –

回答

5

PRG代表後重定向 - 獲得。這意味着當您向服務器返回一些數據時,您應該重定向至GET操作。

爲什麼我們需要這樣做?

想象一下,您有表單,您可以在其中輸入客戶註冊信息,然後單擊提交到HttpPost操作方法的提交。您正在讀取表單中的數據並將其保存到數據庫中,並且您沒有執行重定向。相反,你會留在同一頁面上。現在,如果刷新瀏覽器(只需按F5按鈕)瀏覽器將再次執行類似的表單發佈,並且您的HttpPost Action方法將再次執行相同的操作。即;它會再次保存相同的表單數據。這是個問題。爲了避免這個問題,我們使用PRG模式。

PRG,你點擊提交與該HttpPost操作方法將節省您的數據(或任何它所要做的),然後做一個重定向到一個Get請求。因此,瀏覽器將發送一個Get請求該動作

RedirectToAction方法返回HTTP 302響應瀏覽器,這會導致瀏覽器對指定操作發出GET請求。

[HttpPost] 
public ActionResult SaveCustemer(string name,string age) 
{ 
    //Save the customer here 
    return RedirectToAction("CustomerList"); 

} 

上述代碼將保存數據並重定向到客戶列表操作方法。所以你的瀏覽器網址現在是http://yourdomain/yourcontroller/CustomerList。現在,如果你刷新瀏覽器。 IT不會保存重複的數據。它會簡單地加載CustomerList頁面。

在您的搜索操作方法中,您不需要重定向到獲取操作。您在products變量中具有搜索結果。只需將它傳遞給所需的視圖即可顯示結果。您不必擔心重複的表單發佈。所以你對此很好。

[HttpPost] 
public ActionResult Index(ViewModel model) { 

    if (ModelState.IsValid) { 
     var products = repository.GetProducts(model); 
     return View(products) 
    } 
    return View(model); 
} 
+0

感謝您的解釋和樣品。我假設如果我沒有驗證任何東西,那麼我可以忽略ModelState檢查嗎? – Rich

+0

@Rich。是。如果你沒有驗證任何東西,你可以刪除它(使用最後一個返回的View(model)語句)。 – Shyju

2

重定向只是一個ActionResult,它是另一個操作。所以,如果你有一個動作叫SearchResult所,你就簡單的說

return RedirectToAction("SearchResults"); 

如果這個動作是在另一個控制器...

return RedirectToAction("SearchResults", "ControllerName"); 

隨着參數...

return RedirectToAction("SearchResults", "ControllerName", new { parameterName = model.PropertyName }); 

更新

我想到你可能會所以要選擇發送複雜的對象到下一個動作,在這種情況下,你只有有限的選項,TempData的是首選的方法

用你的方法

[HttpPost] 
public ActionResult Index(ViewModel model) { 
    ... 
    if (ModelState.IsValid) { 
     product = repository.GetProducts(model); 
     TempData["Product"] = product; 
     return RedirectToAction("NextAction"); 
    } 
    return View(model); 
} 

public ActionResult NextAction() { 
    var model = new Product(); 
    if(TempData["Product"] != null) 
     model = (Product)TempData["Product"]; 
    Return View(model); 
} 
+0

+1表示替代。謝謝! – Rich

+0

沒有問題,我upvoted @shyju,因爲他同樣正確:-) –