简体   繁体   English

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

[英]How do I maintain ModelState errors when using RedirectToAction?

I have some code that saves a ticket in our system.我有一些代码可以在我们的系统中保存一张票。 If there is an error it does a RedirectToAction() .如果出现错误,它会执行RedirectToAction() The problem is that I don't seem to have my errors in the new action.问题是我在新动作中似乎没有错误。 How can I fix this?我怎样才能解决这个问题?

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

I know some have suggested using TempData , but how would I get each error out of the ModelState ?我知道有些人建议使用TempData ,但是如何从ModelState中获取每个错误?

Thanks.谢谢。

The PRG pattern is ok, but I did this: PRG 模式没问题,但我这样做了:

Base controller:底座 controller:

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

    base.OnActionExecuted(filterContext);
}

Action (I'm using xVal ):行动(我正在使用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());
}

The action throws an exception, adds the ModelState to TempData and redirects back to the referrer.该操作引发异常,将ModelState添加到TempData并重定向回引荐来源网址。 Since the action is caught, OnActionExecuted is still executed, but the first time around the ModelState is the same as TempData["ModelState"] , so you don't want to merge with yourself.既然动作被抓到了, OnActionExecuted还是会执行,但是第一次绕ModelStateTempData["ModelState"]是一样的,所以不想和自己合并。 When the redirect action is executed, OnActionExecuted fires again.执行重定向操作时, OnActionExecuted再次触发。 This time, if there's anything in TempData["ModelState"] , it merges with this action's ModelState.这一次,如果TempData["ModelState"]中有任何内容,它将与此操作的 ModelState 合并。

You could expand it to multiple models by using TempData["ModelState.user"] = ModelState and then merging every TempData object that starts with ModelState.您可以使用TempData["ModelState.user"] = ModelState将其扩展到多个模型,然后合并每个以 ModelState 开头的TempData ModelState. . .

I know this thread is old, but this blog about ASP.NET Best Practices has some excellent suggestions.我知道这个线程很旧,但是这个关于 ASP.NET 最佳实践的博客有一些很好的建议。
#13 on the page deals with using 2 Action filters to save and restore ModelState between redirects.页面上的 #13 处理使用 2 个操作过滤器在重定向之间保存和恢复ModelState

This is the pattern that my work uses, and I love it.这是我的工作使用的模式,我喜欢它。

Here's the simplified example:这是简化的示例:

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

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

hth hth

Use the TempData[] Collection使用 TempData[] 集合

The tempdata is stored from one request to the next, then its gone.临时数据从一个请求存储到下一个请求,然后就消失了。

What I did to maintain my ModelState no matter where I go with redirects is the following:无论我在哪里使用重定向 go,我为维护我的 ModelState 所做的工作如下:

  1. In your model, add:在您的 model 中,添加:

     public ModelStateDictionary modelstate { get; set; }
  2. In your model's constructor, add:在模型的构造函数中,添加:

     this.modelstate = new System.Web.Mvc.ModelStateDictionary();
  3. Sample Post with my model called Models.ContactInformation:带有我的 model 的示例帖子,称为 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. So now your tempdata has your model and modelstate as is.所以现在你的临时数据有你的 model 和模型状态。

  5. The following is my view that is agnostic to the state of anything, unless it has something.以下是我对任何东西的 state 不可知的观点,除非它有什么东西。 Here's the code:这是代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM