我有一些代码可以在我们的系统中保存票证。如果有错误,它会执行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中获取每个错误?
感谢。
答案 0 :(得分:41)
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());
}
该操作抛出异常,将ModelState添加到TempData并重定向回referrer。由于捕获了动作,OnActionExecuted仍然执行,但ModelState第一次与TempData [“ModelState”]相同,因此您不想与自己合并。执行重定向操作时,OnActionExecuted再次触发。这一次,如果TempData [“ModelState”]中有任何内容,它会与此动作的ModelState合并。
您可以使用TempData [“ModelState.user”] = ModelState将其扩展为多个模型,然后合并以ModelState开头的每个TempData对象。
答案 1 :(得分:29)
我知道这个帖子已经过时了,但this blog about ASP.NET Best Practices有一些很好的建议
页面上的#13处理使用2个动作过滤器在重定向之间保存和恢复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");
}
答案 2 :(得分:4)
此博客文章介绍了如何在MVC中实现PRG-Pattern http://blog.simonlovely.com/archive/2008/11/26/post-redirect-get-pattern-in-mvc.aspx
HTH
答案 3 :(得分:3)
使用TempData [] Collection
tempdata从一个请求存储到下一个请求,然后就消失了。
答案 4 :(得分:0)
无论我在哪里使用重定向,我所做的是维护我的ModelState,如下所示:
在您的模型中,添加:
public ModelStateDictionary modelstate { get; set; }
在模型的构造函数中,添加:
this.modelstate = new System.Web.Mvc.ModelStateDictionary();
我的模型示例帖子名为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");
}
所以现在你的tempdata按原样有你的模型和模型状态。
以下是我对任何事物的状态都不了解的观点,除非它有某些东西。这是代码:
[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);
}