ASP.Net MVC ModelState / Html.TextBox回发问题

我有一个问题出现在我试图发布的表格中。 在表单未validation的情况下,我采用调用ModelState.AddModelError()的标准路由,然后返回View结果。

问题是,HTML。*助手应该在渲染时获取已发布的值,并且我注意到我的文本字段仅在我将其包含在回发操作的参数列表中时才这样做,这不应该是必需的看到某些表单有太多的字段想要将它们全部列为参数。

我的操作代码大致是:

 [AcceptVerbs(HttpVerbs.Post)] public ActionResult EditDataDefinition(long? id, string name) { var dataDefinition = ... // do some validation stuff if (!ModelState.IsValid) { // manually set checkbox fields via ViewData seeing as this STILL doesn't work in MC 1.0 :P // ... return View(dataDefinition); } } 

现在,dataDefinition(这是一个LINQ to SQL实体)有一个MinVolume字段,在这一行的视图中处理:

 Minimum:  

然而,当在ModelStatevalidation失败后呈现视图时,在我们发布的原始页面上输入的值不会被保留,除非我将它作为参数包含在回发方法中。 从字面上看,我可以通过这样做来“解决问题”:

 [AcceptVerbs(HttpVerbs.Post)] public ActionResult EditDataDefinition(long? id, string name, string minVolume) 

由于某种原因,将强制保留字段值。 这对我来说似乎很愚蠢,因为我的表单有更多的价值而不仅仅是那个,我不应该只为该字段添加参数。

有任何想法吗?

可能是你的代码:

 <%= Html.TextBox("MinVolume", null, new { size = 5 })%> 

..是否为默认值param的null ? 也许如果将null更改为Model.MinVolume ,它将保留该值。 像这样:

 <%= Html.TextBox("MinVolume", Model.MinVolume, new { size = 5 })%> 

我不确定你的动作MinVolume在模型中返回值MinVolume 。 如果确实如此,上述情况应该有效。 否则,您可能需要稍微重构该操作。

哦,我刚刚改进了我的应用程序设计。 出现问题是因为您有自定义validation(我也有)。 你必须在之后添加

 ModelState.AddModelError() 

这个

 ModelState.SetModelValue("MinVolume", ValueProvider["MinVolume"]); 

鉴于它必须是

 Mimum:<%=Html.Textbox("MinVolume")%> 

仍然不确定为什么它有效,但它对我有用。

在错误中设置ModelState中的值时,您使用的密钥是什么? 为TextBox设置value参数的代码如下所示:

下载的框架代码的相关部分。

 string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string)); tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue); 

正如您所看到的那样,尝试值是否存在,它将使用它 – 但仅当相同的密钥可用时才会使用它。

我知道这是有效的,因为我有一个不带参数的动作,直接从ValueProvider获取值,它使用AddModelError来指示validation错误。 我确信我的TextBox中的值是保留的。

编辑 :为了保留值,它们需要以某种方式与模型相关联。 一种方法是将它们添加到参数列表中。 另一种方法是使用UpdateModel(白名单中的参数名称或没有白名单)。 第三种方法是将参数显式添加到模型中,如@ Jenea的答案。 由于辅助程序仅从模型状态拉出,因此它们必须位于其中以保留值。 它不会查看请求的Form属性。

据我所知,解决方案是:

 [Transaction] [AcceptVerbs(HttpVerbs.Post)] public ActionResult EditDataDefinition(int id, FormCollection form) { T itemToUpdate = repository.Get(id); UpdateModel(itemToUpdate, form.ToValueProvider()); if (itemToUpdate.IsValid()) { repository.SaveOrUpdate(itemToUpdate); return Json(ValidationResultToJson(itemToUpdate.ValidationResults())); } repository.DbContext.RollbackTransaction(); return Json(ValidationResultToJson(itemToUpdate.ValidationResults())); } 

祝好运!

另一种解决方案是输入视图:

 <%var minVolume=Request["MinVolume"]??"";%> <%=Html.Textbox("MinVolume",minVolume,new {size=5})%> 

请参阅这篇文章,了解在ASP.NET MVC中处理回发的不同方法

链接文字