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

时间:2009-05-07 14:05:49

标签: c# asp.net-mvc html-helper

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

问题是,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: <%= Html.TextBox("MinVolume", null, new { size = 5 })%>

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

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

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

有什么想法吗?

6 个答案:

答案 0 :(得分:6)

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

后添加
ModelState.AddModelError()

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

在视野中它必须是

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

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

答案 1 :(得分:4)

可能是你的代码:

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

..默认值param有null吗?也许如果您将null更改为Model.MinVolume,它会保留该值。像这样:

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

我不确定您的操作是否在模型中返回值MinVolume。如果是这样,上述应该有效。否则,您可能需要稍微重构一下这个动作。

答案 2 :(得分:3)

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

downloaded framework code的相关部分。

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

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

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

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

答案 3 :(得分:0)

据我所知,解决方案是:

[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()));
}
祝你好运!

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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

link text