本文介绍了ASP.NET MVC向导问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我已经使用这个岗位创造asp.net的MVC向导:
multi-step在asp.net mvc的注册过程中的问题(分裂的ViewModels,单一的模式)

Hi i've used this post to create a wizard in asp.net mvc:multi-step registration process issues in asp.net mvc (splitted viewmodels, single model)

它只能与在接口背后的具体类dataannotations
        IStepViewModel

It works only with dataannotations on the concrete classes behind the interface IStepViewModel

是否有可能在StepViewModelBinder添加一些功能上的具体步骤执行ModelBinder的?

Is it possible in the StepViewModelBinder to add some functionality to execute a modelbinder on the concrete steps?

在此先感谢

推荐答案

找到了解决办法。 Unfornutanetely它不是在通用作为原始 - 但它允许modelbinders为的ViewModels

Found a solution. Unfornutanetely it is not at generic as the original - but it allows modelbinders for the viewmodels.

我替换下原有的StepViewModelBinder:

I replaced the original StepViewModelBinder with the following:

 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);
    }

}

该解决方案得到了模型的相关ModelBinder的 - 不利的一面是,由于具体的实施是隐藏在接口后面,一个ModelBinder的就是要求为具体的实施工作,因为一个具体的类型不能从接口实例

this solution gets the associated modelbinder for the model - the downside is, since the concrete implementation is hidden behind an interface, a modelbinder is required to work for the concrete implementation, since a concrete type cannot be instantiated from an interface

在ModelBinder的为混凝土类,那么可以看看如下:

THe modelbinder for the concrete class could then look as follows:

  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;
    }

在ModelBinder的是一起作为视图模型通常结合,或者通过

the modelbinder is coupled together with the viewmodel as usually, either by

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

或类注释:

[ModelBinder(typeof(OpretBrugerStep1ModelBinder))]

我刚创建的步骤的实现的通用默认ModelBinder的,并不需要具体的实施 - 只是为了让它们与例子来工作:

I've just created a generic default modelbinder for the step-implementations that does not need a specific implementation - just to get them to work with the example:

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;
        }
    }

这样的具体步骤菅直人使用这个模型绑定器 - 例如用于步骤1:

Thus the concrete steps kan use this modelbinder - example for step1:

 [ModelBinder(typeof(DefaultStepModelBinder<Step1>))]
[Serializable]
public class Step1 : IStepViewModel
{ ... }

这篇关于ASP.NET MVC向导问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-02 16:45