2

我有一个帐户用户名的备份变量,我通过隐藏字段中的帖子保存它,@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就会恢复到更改任何内容之前的状态。我在这里想念什么?表单的——因此隐藏字段的——值不应该从传入的模型中重新填充吗?

4

2 回答 2

1

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

最佳解决方案是在操作成功时使用Post-Redirect-Get 模式,但如果您认为不需要它,您可以告诉 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);
}
于 2013-09-17T20:22:00.413 回答
0

这里找到解决方案:我所要做的就是在验证/执行任何操作之前清除 ModelState,这样旧值就不会被保留。

于 2013-09-18T13:55:09.083 回答