1

我正在尝试使用单个控制器操作并根据模型上的值返回视图的多页表单。

我的模型有一个属性,我使用 Html.HiddenFor() 在视图的输入字段中放置了该属性。

这是我的简化模型:

public class MyModel 
{
   public virtual int Step { get; set; }
}

在我看来,我有:

@model MyModel
...
@Html.HiddenFor(model => model.Step)

然后在我的控制器中,我有:

public ActionResult Create()
{
    ...
    myModel.Step = 1;
    return View("View1", myModel);
}

[HttpPost]
public ActionResult Create(MyModel myModel)
{
    ...
    if (myModel.Step == 1)
    {
        myModel.Step = 2;
        return View("View2", myModel);
    }
    else if (myModel.Step == 2)
    {
        ...
    }
    ...
}

我的问题是,我的控制器总是认为 mymodel.Step 的值为 1。这是为什么呢?

奇怪的是,我试图用这些在表单上显示它:

@Html.DisplayFor(model => model.Step)
@Html.EditorFor(model => model.Step)

第二次显示页面时,第一行显示文本“2”。第二个显示带有“1”的输入字段。我很困惑。

附加信息:

我的模型还有一个 Guid 属性,该属性在隐藏字段中传递给视图。我也尝试在回发时更改它,并第二次检查它的值。新值未注册。该模型在第一次发布之前返回了原始值。所以它与其他领域是一致的。

如果我无法找到它目前的行为方式,我可能不得不使用不同的控制器操作。

解决方案:

正如 Reda 在下面建议的那样,我通过在我的 post 操作方法中执行此操作来修复它:

  • 在显示“View2”并影响我的控制器对模型中的值所做的更改之前,我运行 ModelState.Clear()

这是一篇博客文章,确认需要为此场景清除 ModelState。

4

1 回答 1

4

通常,当您从 post 操作返回视图时,这意味着验证过程中发生了一些错误,并且应该再次显示表单以及提交的值。这就是为什么ModelState当您返回 View 时会记住您的输入,并且您的输入将从 而ModelState不是您的视图模型中填充。

在我看来,您有两种解决方案:

  • ModelState.Clear,这将在设置新值之前删除您的旧值
  • 使用新值重定向到 GET 操作

第二种解决方案更好,因为您不会显示带有验证错误的旧表单,而只是显示具有不同值的新视图。

这是一个示例(当然您可以根据自己的需要进行调整):

public ActionResult Create(int? step)
{
    ...
    myModel.Step = step.HasValue ? step.Value : 1; // or whatever logic you need to apply
    return View("View1", myModel);
}

[HttpPost]
public ActionResult Create(MyModel myModel)
{
    ...
    if (myModel.Step == 1)
    {
        return RedirectToAction("Create", new { step = 2 });
    }
    else if (myModel.Step == 2)
    {
        ...
    }
    ...
}
于 2013-11-12T09:40:32.717 回答