【问题标题】:Wrong default form values from model模型中的错误默认表单值
【发布时间】:2013-09-17 20:05:54
【问题描述】:

我有一个帐户用户名的备份变量,我通过隐藏字段@Html.HiddenFor(u => u.backupUsername) 中的帖子保存该变量。这是表单发布到的功能:

    [HttpPost]
    public ActionResult Update(AccountModel newInfo)
    {
        validateUserInfo(newInfo);
        if (ModelState.IsValid)
        {
            newInfo.updateToDatabase();
        }
        TempData["ModelState"] = ModelState;
        TempData["SomeModel"] = newInfo;
        return RedirectToAction("Main");
    }

    [HttpGet]
    public ActionResult Main()
    {
        if (TempData.ContainsKey("ModelState"))
        {
            ModelState.Merge((ModelStateDictionary)TempData["ModelState"]);
            return View("View", (SomeModel)TempData["SomeModel"]);
        }
    }

updateToDatabase() 中,更新备份用户名以匹配当前用户名。我设置了断点并在调试期间查看了值,以确认这确实发生并且有效。

但是,一旦再次调用 Update()newInfo.backupUsername 就会恢复到更改之前的状态。我在这里想念什么?不应该从传入的模型中重新填充表单的值(以及隐藏字段的值)吗?

【问题讨论】:

  • 查看 HTML 源码时,隐藏元素的值是否正确?
  • @asymptoticFault 不,相同的未更改,错误的值。
  • @asymptoticFault 是的,不幸的是不起作用。

标签: c# asp.net-mvc-4 razor


【解决方案1】:

由于您在 POST 请求后返回另一个视图,因此 ASP.NET MVC 认为验证失败并显示请求中的旧值。模型实例中的更改将被忽略。您可以阅读此blog post 以获得详细说明。

最好的解决方案是在操作成功时使用Post-Redirect-Get pattern,但如果您认为不需要它,您可以告诉 ASP.NET MVC 忽略请求中的原始值。

[HttpPost]
public ActionResult Update(AccountModel newInfo)
{
    validateUserInfo(newInfo);
    if (ModelState.IsValid)
    {
        newInfo.updateToDatabase();
    }
    ModelState.Clear();
    return View(newInfo); 
}

我不能最简单的方法是实现 Post-Redirect-Get 会是这样的:

[HttpPost]
public ActionResult Update(AccountModel newInfo)
{
    validateUserInfo(newInfo);
    if (ModelState.IsValid)
    {
        newInfo.updateToDatabase();
        TempData["newInfo"] = newInfo;       
        return RedirectToAction("Main");
    }
    return View(newInfo);
}

[HttpGet]
public ActionResult Main()
{
    var model = (TempData["newInfo"] as AccountModel) ?? new AccountModel();//or some other way to populate the model when it'not redirected from Update method.
    return View("View", model);
}

【讨论】:

  • 感谢您的解释。我现在把return改成了RedirectToAction("Main"),通过TempData把model和ModelState传给Main(),但是隐藏字段的值还是没变。如果我想显示新值,我应该使用什么?
  • @idlackage 你也可以发布那个方法吗?
  • @idlackage 我认为您需要将 newInfo 存储在 TempData 并在 Main 方法中检索它。
  • 哎呀抱歉,我在为帖子重命名变量时打错了!
  • @idlackage 很奇怪。你在 ModelState 中看到什么备份用户名?
【解决方案2】:

here 找到解决方案:我所要做的就是在验证/执行任何操作之前清除 ModelState,以免保留旧值。

【讨论】:

  • 我在最初的回答中提出了这个建议。它不适合你?
  • @UfukHacıoğulları 我实际上并没有最终尝试它,因为我想保留 ModelState 错误并且不知道 ModelState.Clear() 除了摆脱这些错误之外会做什么,因此不再进一步研究它。既然您已经告诉我有关在 ModelState 中查找值并将我的注意力转移到它上,那么我对它的理解要好得多,并看看它是如何工作的。非常抱歉,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
  • 2015-04-06
  • 2015-04-19
  • 1970-01-01
  • 2022-06-17
相关资源
最近更新 更多