当我使用默认模型绑定将表单参数绑定到作为操作参数的复杂对象时,框架会记住传递给第一个请求的值,这意味着对该操作的任何后续请求都会获得与第一个请求相同的数据。参数值和验证状态在不相关的 Web 请求之间保持不变。
这是我的控制器代码(service
代表对应用程序后端的访问):
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Create()
{
return View(RunTime.Default);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(RunTime newRunTime)
{
if (ModelState.IsValid)
{
service.CreateNewRun(newRunTime);
TempData["Message"] = "New run created";
return RedirectToAction("index");
}
return View(newRunTime);
}
我的 .aspx 视图(强类型为ViewPage<RunTime
>)包含如下指令:
<%= Html.TextBox("newRunTime.Time", ViewData.Model.Time) %>
这使用了DefaultModelBinder
该类,该类旨在自动绑定我的模型的 properties。
我点击页面,输入有效数据(例如时间 = 1)。该应用程序正确保存了时间 = 1 的新对象。然后我再次点击它,输入不同的有效数据(例如时间 = 2)。但是,保存的数据是原始数据(例如时间 = 1)。这也会影响验证,所以如果我的原始数据无效,那么我以后输入的所有数据都被认为是无效的。重新启动 IIS 或重建我的代码会刷新持久状态。
我可以通过编写自己的硬编码模型绑定器来解决这个问题,下面显示了一个基本的简单示例。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([ModelBinder(typeof (RunTimeBinder))] RunTime newRunTime)
{
if (ModelState.IsValid)
{
service.CreateNewRun(newRunTime);
TempData["Message"] = "New run created";
return RedirectToAction("index");
}
return View(newRunTime);
}
internal class RunTimeBinder : DefaultModelBinder
{
public override ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
// Without this line, failed validation state persists between requests
bindingContext.ModelState.Clear();
double time = 0;
try
{
time = Convert.ToDouble(bindingContext.HttpContext.Request[bindingContext.ModelName + ".Time"]);
}
catch (FormatException)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName + ".Time", bindingContext.HttpContext.Request[bindingContext.ModelName + ".Time"] + "is not a valid number");
}
var model = new RunTime(time);
return new ModelBinderResult(model);
}
}
我错过了什么吗?我不认为这是浏览器会话问题,因为如果在一个浏览器中输入第一个数据而在另一个浏览器中输入第二个数据,我可以重现该问题。