模型中的默认表单值错误

时间:2013-09-17 20:05:54

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

我有一个帐户用户名的备用变量,我通过隐藏字段@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就会恢复到更改之前的状态。我在这里错过了什么?表格的 - 以及隐藏的字段 - 值是否应该从传入的模型中重新填充?

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

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