Asp.net-Mvc
ASP.NET MVC - 如何跨 RedirectToAction 保留 ModelState 錯誤?
我有以下兩種操作方法(為問題而簡化):
所以,如果驗證通過,我會重定向到另一個頁面(確認)。
如果發生錯誤,我需要顯示與錯誤相同的頁面。
如果我這樣做
return View(),則會顯示錯誤,但如果我這樣做return RedirectToAction(如上所述),它會失去模型錯誤。我對這個問題並不感到驚訝,只是想知道你們如何處理這個問題?
我當然可以只返回相同的視圖而不是重定向,但是我在填充視圖數據的“創建”方法中有邏輯,我必須複製這些數據。
有什麼建議?
您需要
Review在您的HttpGet操作上有相同的實例。為此,您應該在操作時將對象保存Review review在臨時變數中HttpPost,然後在HttpGet操作時將其恢復。[HttpGet] public ActionResult Create(string uniqueUri) { //Restore Review review = TempData["Review"] as Review; // get some stuff based on uniqueuri, set in ViewData. return View(review); } [HttpPost] public ActionResult Create(Review review) { //Save your object TempData["Review"] = review; // validate review if (validatedOk) { return RedirectToAction("Details", new { postId = review.PostId}); } else { ModelState.AddModelError("ReviewErrors", "some error occured"); return RedirectToAction("Create", new { uniqueUri = Request.RequestContext.RouteData.Values["uniqueUri"]}); } }如果您希望即使在第一次執行
HttpGet操作後刷新瀏覽器也能正常工作,您可以這樣做:Review review = TempData["Review"] as Review; TempData["Review"] = review;否則刷新按鈕對象
review將為空,因為TempData["Review"].
我今天不得不自己解決這個問題,並遇到了這個問題。
有些答案很有用(使用 TempData),但並沒有真正回答手頭的問題。
我發現的最佳建議是在這篇博文中:
<http://www.jefclaes.be/2012/06/persisting-model-state-when-using-prg.html>
基本上,使用 TempData 來保存和恢復 ModelState 對象。但是,如果您將其抽象為屬性,它會更簡潔。
例如
public class SetTempDataModelStateAttribute : ActionFilterAttribute { public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); filterContext.Controller.TempData["ModelState"] = filterContext.Controller.ViewData.ModelState; } } public class RestoreModelStateFromTempDataAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); if (filterContext.Controller.TempData.ContainsKey("ModelState")) { filterContext.Controller.ViewData.ModelState.Merge( (ModelStateDictionary)filterContext.Controller.TempData["ModelState"]); } } }然後根據您的範例,您可以像這樣保存/恢復 ModelState:
[HttpGet] [RestoreModelStateFromTempData] public ActionResult Create(string uniqueUri) { // get some stuff based on uniqueuri, set in ViewData. return View(); } [HttpPost] [SetTempDataModelState] public ActionResult Create(Review review) { // validate review if (validatedOk) { return RedirectToAction("Details", new { postId = review.PostId}); } else { ModelState.AddModelError("ReviewErrors", "some error occured"); return RedirectToAction("Create", new { uniqueUri = Request.RequestContext.RouteData.Values["uniqueUri"]}); } }如果您還想在 TempData 中傳遞模型(如 bigb 建議的那樣),那麼您仍然可以這樣做。