使用RedirectToAction时如何维护ModelState错误?

我有一些代码可以在我们的系统中保存票证。 如果有错误,它会执行RedirectToAction。 问题是我似乎没有在新动作中出现错误。 我怎样才能解决这个问题?

ModelState.AddModelError("_FORM", "Unable to save ticket"); ModelState.AddModelError("_FORM", "Phone number was invalid."); ModelState.AddModelError("_FORM", "Lane number is required."); return RedirectToAction("CreateStep", "Ticket"); 

我知道有人建议使用TempData,但是如何从ModelState中获取每个错误?

谢谢。

PRG模式还可以,但我这样做了:

基础控制器:

 protected override void OnActionExecuted(ActionExecutedContext filterContext) { if (TempData["ModelState"] != null && !ModelState.Equals(TempData["ModelState"])) ModelState.Merge((ModelStateDictionary)TempData["ModelState"]); base.OnActionExecuted(filterContext); } 

动作(我正在使用xVal ):

 try { user.Login(); AuthenticationManager.SignIn(user); } catch (RulesException rex) { // on bad login rex.AddModelStateErrors(ModelState, "user"); TempData["ModelState"] = ModelState; return Redirect(Request.UrlReferrer.ToString()); } 

该操作抛出exception,将ModelState添加到TempData并重定向回引用者。 由于操作被捕获,OnActionExecuted仍然执行,但第一次围绕ModelState与TempData [“ModelState”]相同,因此您不希望与自己合并。 执行重定向操作时,OnActionExecuted再次触发。 这一次,如果TempData [“ModelState”]中有任何内容,它会与此动作的ModelState合并。

您可以使用TempData [“ModelState.user”] = ModelState将其扩展为多个模型,然后合并以ModelState开头的每个TempData对象。

我知道这个post已经过时了,但是关于ASP.NET最佳实践的博客有一些很好的建议。
页面上的#13处理使用2个Actionfilter在重定向之间保存和恢复ModelState

这是我的作品使用的模式,我喜欢它。

这是简化的例子:

 [ImportModelStateFromTempData] public ActionResult Dashboard() { return View(); } [AcceptVerbs(HttpVerbs.Post), ExportModelStateToTempData] public ActionResult Dashboard(string data) { if (ValidateData(data)) { try { _service.Submit(data); } catch (Exception e) { ModelState.AddModelError(ModelStateException, e); } } return RedirectToAction("Dashboard"); } 

这篇博文描述了如何在MVC中实现PRG模式http://blog.simonlovely.com/archive/2008/11/26/post-redirect-get-pattern-in-mvc.aspx

心连心

使用TempData []集合

tempdata从一个请求存储到下一个请求,然后它就消失了。

无论我在哪里使用重定向,我所做的是维护我的ModelState,如下所示:

  1. 在您的模型中,添加:

     public ModelStateDictionary modelstate { get; set; } 
  2. 在模型的构造函数中,添加:

     this.modelstate = new System.Web.Mvc.ModelStateDictionary(); 
  3. 我的模型示例post名为Models.ContactInformation:

     [HttpPost] [ValidateAntiForgeryToken] public ActionResult contact(Models.ContactInformation con) { if (string.IsNullOrEmpty(con.SelectedAgencySelectorType)) { ModelState.AddModelError("", "You did not select an agency type."); } con.modelstate = ModelState; TempData["contact"] = con; if (!ModelState.IsValid) return RedirectToAction("contactinformation", "reports"); //do stuff return RedirectToAction("contactinformation", "reports"); } 
  4. 所以现在你的tempdata有你的模型和模型状态。

  5. 以下是我对任何事物的状态都是不可知的观点,除非它有某些东西。 这是代码:

     [HttpGet] public ActionResult contactinformation() { //try cast to model var m = new Models.ContactInformation(); if (TempData["contact"] is Models.ContactInformation) m = (Models.ContactInformation)TempData["contact"]; //restore modelstate if needed if (!m.modelstate.IsValid) { foreach (ModelState item in m.modelstate.Values) { foreach (ModelError err in item.Errors) { ModelState.AddModelError("", err.ErrorMessage.ToString()); } } } return View(m); } 

我相信当你进行重定向时你会失去模型状态。 也许你可以将你的逻辑重写为:

 public ActionResult Save() { // your code... if(saveSucceeded) { return View("Saved"); } else { return View("Create"); } } 

以及获取错误消息的常用方法:

 <%= Html.ValidationMessage("property_name") %>