gpt4 book ai didi

asp.net-mvc - ASP.NET MVC 测试版 1 : DefaultModelBinder wrongly persists parameter and validation state between unrelated requests

转载 作者:行者123 更新时间:2023-12-02 02:50:05 24 4
gpt4 key购买 nike

当我使用默认模型绑定(bind)将表单参数绑定(bind)到作为操作参数的复杂对象时,框架会记住传递给第一个请求的值,这意味着对该操作的任何后续请求都会获取与首先。参数值和验证状态在不相关的 Web 请求之间保留。

这是我的 Controller 代码( 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 View (强类型为 ViewPage<RunTime >)包含如下指令:

<%= Html.TextBox("newRunTime.Time", ViewData.Model.Time) %>

这使用 DefaultModelBinder类,即 meant to autobind my model's properties .

我点击页面,输入有效数据(例如时间= 1)。应用程序正确保存了时间 = 1 的新对象。然后我再次点击它,输入不同的有效数据(例如时间 = 2)。然而,保存的数据是原始数据(例如时间= 1)。这也会影响验证,因此如果我的原始数据无效,那么我以后输入的所有数据都被视为无效。重新启动 IIS 或重建代码会刷新持久状态。

我可以通过编写自己的硬编码模型绑定(bind)器来解决该问题,下面显示了一个基本的简单示例。

    [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);
}
}

我错过了什么吗?我不认为这是浏览器 session 问题,因为如果在一个浏览器中输入第一个数据,在另一个浏览器中输入第二个数据,我可以重现该问题。

最佳答案

事实证明,问题在于我的 Controller 在调用之间被重复使用。我选择从原始帖子中省略的细节之一是我正在使用 CaSTLe.Windsor 容器来创建 Controller 。我未能用 Transient 生活方式标记我的 Controller ,因此我在每个请求中都得到了相同的实例。因此,绑定(bind)器使用的上下文被重新使用,当然它包含过时的数据。

我在仔分割析 Eilon 的代码和我的代码之间的差异时发现了这个问题,排除了所有其他可能性。作为Castle documentation says ,这是一个“可怕的错误”!让这成为对其他人的警告!

感谢您的回复 Eilon - 很抱歉占用您的时间。

关于asp.net-mvc - ASP.NET MVC 测试版 1 : DefaultModelBinder wrongly persists parameter and validation state between unrelated requests,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/238460/

24 4 0