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