MVC Controller返回不同的视图;模型数据未保存在隐藏输入中

时间:2013-11-12 09:03:09

标签: asp.net-mvc

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

我的模型有一个属性,我使用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属性,它在隐藏字段中传递给View。我试图在回发时更改它,并在第二次检查它的值。新值没有注册。模型在第一篇文章之前返回原始值。所以它与其他领域一致。

我可能不得不使用不同的控制器操作,如果我找不到为什么它的行为与此刻相同。

SOLUTION:

正如Reda在下面提到的那样,我通过我的后期操作方法来修复它:

  • 在显示“View2”并实现更改之前,我的控制器在我的模型中创建一个值,我运行ModelState.Clear()

这是一个blog post,它确认需要为此方案清除ModelState。

1 个答案:

答案 0 :(得分:3)

通常,当您从后期操作返回到查看时,这意味着在验证过程中某些内容失败,并且应该使用提交的值再次显示该表单。这就是为什么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)
    {
        ...
    }
    ...
}