Mvc3中的模型绑定 - 模型在动作之间通过表单发布 - 如何持久化

时间:2012-06-01 13:13:14

标签: c# asp.net-mvc-3

我有一个多步骤向导,我从this等有用的帖子中拼凑起来但是它有一些问题但是这里是我的设置

[Serializable]
public class WizardModel
{

    public IList<IStepViewModel> Steps 
    { 
        get; 
        set; 
    }
    public void Initialize()
    {
        Steps = typeof(IStepViewModel)
            .Assembly
            .GetTypes()
            .Where(t => !t.IsAbstract && typeof(IStepViewModel).IsAssignableFrom(t))
            .Select(t => (IStepViewModel)Activator.CreateInstance(t))
            .ToList();
    }

}

我的向导控制器

    public ActionResult Index()
    {
        var wizard = new WizardModel();     
        wizard.Initialize();
        //this populates wizard.Steps with 3 rows of IStepViewModel
        return View(rollover);       
    }

    [HttpPost]
    public ActionResult Index(
        [Deserialize] WizardModel wizard,
        IStepViewModel step
        )
    {
        //but when this runs wizard is a new class not the one previously Initialized
         wizard.Steps[rollover.CurrentStepIndex] = step;
    }

我的问题是每次发布时向导都是一个新对象 - 当我试图通过填充数组中的每个步骤来传递相同的模型时。有没有人知道我在哪里出错?

这是ModelBinding

Global.asax中

   ModelBinders.Binders.Add(typeof(IStepViewModel), new FormTest.Models.StepViewModelBinder());

  public class StepViewModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var stepTypeValue = bindingContext.ValueProvider.GetValue("StepType");
        var stepType = Type.GetType((string)stepTypeValue.ConvertTo(typeof(string)), true);
        var step = Activator.CreateInstance(stepType);
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => step, stepType);
        return step;
    }
}

提前致谢

修改

如果我理解,使用session的替代方法是序列化我的模型(下面),并在我的控制器操作中反序列化。我在模型上设置了发布到控制器的值..它将返回到下一步的视图,依此类推......直到最后一步,我有一个向导模型填充每一步。

Index.cshtml

   @using (Html.BeginForm())
   {
         @Html.Serialize("wizard", Model);  
         etc...
   }   

所以我尝试反序列化的向导参数

    [Deserialize] WizardModel wizard,

来自控制器post post每次都是一个新对象 - 我想看看这是否可以不使用Session而是@Html.Serialize?并发布

3 个答案:

答案 0 :(得分:1)

使用会话在请求之间保留对象。

Session["SuperWizard"] = wizard

答案 1 :(得分:1)

这段代码最终完成了这项工作。在控制器动作中,

        var serializer = new MvcSerializer();
        var value = Request["wizard"];
        var wizard = (WizardModel)serializer.Deserialize(value, SerializationMode.Signed);

在视图中

    @Html.Serialize("wizard", Model, SerializationMode.Signed);   

答案 2 :(得分:0)

模型绑定用于将POSTed表单值绑定到新对象。因此,如果你想要完全相同的对象,就像迈克建议的那样,你将需要使用Session或其他一些持久存储。但是,如果每次都可以重新创建对象,那么您只需要在表单中放入足够的数据,这样当它被POST时,所有内容都可以重新数据绑定,以便在新对象中获得相同的值。