使用自定义模型绑定器进行递归模型绑定

时间:2012-08-02 10:26:32

标签: c# .net asp.net-mvc-3 model-binding asp.net-mvc-futures

我正在尝试使用.NET MVC在我的表单中实现向导功能。我遇到了Darin Dimitrov的method of achieving。基本上他有一个向导视图模型,其中包含一个ISteps列表。每个步骤都有自己的属性和验证。

他在视图上序列化向导(作为一种视图状态),然后将其和当前步骤发布到控制器。因此,向导的每个步骤都只验证该步骤。如果成功,则递增当前步骤并重复。

在大多数情况下 - 这很有效。但是,在验证各个步骤时遇到了一个问题,因为我的一些步骤依赖于先前提交的验证值。

因此,我需要添加一种方法,允许各个向导步骤访问前面的步骤。

我决定这样做的方法是在步骤中包含向导。

public interface IWizardStep
{
    WizardViewModel Wizard { get; set; }
}

然后在Darin提供的模型绑定器中,为BindModel添加覆盖

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    var step = (IStepViewModel)base.BindModel(controllerContext, bindingContext);
    step.Wizard = (WizardViewModel)serializer.Deserialize(controllerContext.HttpContext.Request.Form["wizard"], SerializationMode.Signed);
    return step;
}

这似乎有效,但是在我的控制器中我有一个ModelStateError:

  

从类型'System.String'到类型的参数转换   '向导'失败,因为没有类型转换器可以   在这些类型之间转换。

我认为这是因为模型绑定器试图递归绑定?

有谁知道我怎么解决这个问题?或者 - 我是否正确接近这个?有更好的方法吗?

我已将以上所有内容都设为basic sample project来说明我遇到的问题。

2 个答案:

答案 0 :(得分:1)

将其添加到HomeController中,作为第18行...

ModelState.Remove("Wizard");

你应该有什么工作,但更好的方法可能是将所有步骤的属性添加到单个模型类中,然后为每个步骤使用验证组......

https://nuget.org/packages/Mvc3ValidationGroups

答案 1 :(得分:0)

所以我从来没有深究这为什么没有工作,但决定在头脑中保存头痛并在会话中保存向导,而不是序列化并将其发回每一步。这样,我可以轻松地在视图模型的Validate(ValidationContext)方法中获取向导。似乎运作良好。