ASP.NET MVC Wizard проблема

Привет, я использовал этот пост, чтобы создать мастера в asp.net mvc: проблемы многоэтапной регистрации в asp.net mvc (разделенные модели, одна модель)

Работает только с аннотациями данных по конкретным классам за интерфейсом IStepViewModel

Возможно ли в StepViewModelBinder добавить некоторые функции для выполнения связывателя модели на конкретных этапах?

заранее спасибо

1 ответ

Решение

Нашел решение. К сожалению, он не является универсальным, как оригинал, но он позволяет связывать модели моделям вида.

Я заменил оригинальный 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;
        }
    }

Таким образом, конкретные шаги kan используют это связующее модель - пример для step1:

 [ModelBinder(typeof(DefaultStepModelBinder<Step1>))]
[Serializable]
public class Step1 : IStepViewModel
{ ... }
Другие вопросы по тегам