1

嗨,我使用这篇文章在 asp.net mvc 中创建了一个向导:asp.net mvc 中的 多步骤注册过程问题(拆分视图模型,单一模型)

它仅适用于接口 IStepViewModel 后面的具体类的数据注释

是否可以在 StepViewModelBinder 中添加一些功能以在具体步骤上执行模型绑定器?

提前致谢

4

1 回答 1

0

找到了解决方案。不幸的是,它不像原来的那样通用 - 但它允许视图模型的模型绑定器。

我用以下内容替换了原来的 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;
    }
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        //bind using default binding, and calls the overriden "CreateModel"
        var model = base.BindModel(controllerContext, bindingContext);

        //if the modelstate is not valid return to controller with found error
        if (!bindingContext.ModelState.IsValid)
            return model;

        //if the modelstate is valid, call the modelbinder for the concreteType
        var ll = Binders.GetBinder(model.GetType());
        return ll.BindModel(controllerContext, bindingContext);
    }

}

此解决方案为模型获取关联的模型绑定器 - 缺点是,由于具体实现隐藏在接口后面,因此需要模型绑定器来为具体实现工作,因为无法从接口实例化具体类型

具体类的模型绑定器可能如下所示:

  protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var step = new Step1();
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => step, step.GetType());
        return step;
    }
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = (Step1)base.BindModel(controllerContext, bindingContext);
        bindingContext.ModelState.AddModelError("", "This is a test");
        return model;
    }

模型绑定器通常与视图模型耦合在一起,或者通过

ModelBinders.Binders.Add(typeof(Step1), new Step1ModelBinder());

或通过类注释:

[ModelBinder(typeof(OpretBrugerStep1ModelBinder))]

我刚刚为不需要特定实现的步骤实现创建了一个通用的默认模型绑定器 - 只是为了让它们与示例一起工作:

public class DefaultStepModelBinder<T> : DefaultModelBinder where T : IStepViewModel, new()
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            var step = new T();
            bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => step, step.GetType());
            return step;
        }
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var model = (T)base.BindModel(controllerContext, bindingContext);
            return model;
        }
    }

因此,具体步骤可以使用此模型绑定器 - step1 的示例:

 [ModelBinder(typeof(DefaultStepModelBinder<Step1>))]
[Serializable]
public class Step1 : IStepViewModel
{ ... }
于 2013-06-27T09:01:01.927 回答