A создал новый CustomModelBinder из того, который уже работал. Почему новый никогда не вызывается для выполнения каких-либо обязательств? - PullRequest
5 голосов
/ 27 июля 2011

Могу ли я сделать что-то подобное?

[HttpPost]
public ActionResult Index(WizardViewModel wizard, IStepViewModel step)
{

Где у меня есть следующее в моем global.asax.cs application_start

    ModelBinders.Binders.Add(typeof(IStepViewModel), new StepViewModelBinder());
    ModelBinders.Binders.Add(typeof(WizardViewModel), new WizardViewModelBinder());

Обновление

Итак,Я пытался понять, что не так.Вот мой новый код.Кажется, что проблема с этим WizardViewModel, и это связыватель.Что «сообщает» приложению об ожидаемой и входящей модели мастера?

[HttpPost]
public ActionResult Index(WizardViewModel wizard)
{

Где у меня есть следующее в моем global.asax.cs application_start

    ModelBinders.Binders.Add(typeof(WizardViewModel), new WizardViewModelBinder());

Полный код связующего

namespace Tangible.Binders
{
    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 class WizardViewModelBinder : DefaultModelBinder
    {
        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
                var wizardValue = bindingContext.ValueProvider.GetValue("wizard");
                if (wizardValue != null)
                {
                    var wizardType = Type.GetType((string)wizardValue.ConvertTo(typeof(string)), true);
                    var wizard = Activator.CreateInstance(wizardType);

                    bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => wizard, wizardType);
                    return wizard;
                }
                else
                {
                    var wizard = new Tangible.Models.WizardViewModel();
                    wizard.Initialize();
                    return wizard;
                }
        }
    }
}

Ответы [ 4 ]

3 голосов
/ 04 августа 2011

Ответ прост - да!Это то, что вы ДОЛЖНЫ делать, когда у вас есть собственная логика для привязки значений к вашим параметрам.Вы даже можете сделать это с помощью ModelBinderAttribute , установленного для каждого из параметров в отдельности.

    [HttpPost]
    public ActionResult Index([ModelBinder(typeof(WizardViewModelBinder))]WizardViewModel wizard, 
[ModelBinder(typeof(StepViewModelBinder))]IStepViewModel step)
    { }

И, как я вижу, ошибка в коде связывания вашей модели.У меня нет времени, чтобы проверить это, но, насколько я помню, CreateModel используется связывателем модели для создания экземпляра модели, а затем этот возвращаемый экземпляр привязывается к модели.Итак, переопределите BindModel вместо CreateModel и запишите логику привязки модели в BindModel.Это определенно работает.

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
{
//your model binding logic here
}
0 голосов
/ 07 августа 2011

Я был действительно разочарован обручами, которые связывало модель ASP.NET MVC Model, чтобы я перескочил, чтобы получить некоторую базовую десериализацию.

Поскольку привязка модели была далеко не такой прозрачной, как я надеялся на сложные Model / ViewModels, я просто создал собственный ActionFilter для разрешения типов [и ТОЛЬКО типов], которые я хочу десериализовать в методе действия и использовать ServiceStack.Text для всех моих потребностей в сериализации / десериализации.

Взгляните сюда:

https://gist.github.com/3b18a58922fdd8d5a963

0 голосов
/ 03 августа 2011

Я бы сказал, что ответ просто: Да! В вашем комментарии вы обеспокоены "многими другими проблемами", которые могут вызвать проблемы. Не зная, какие проблемы вы имеете в виду, вам трудно помочь. Но то, что вы сделали, это именно то, для чего предназначены модели связующих. И нет причины, по которой у вас должен быть только один объект на действие.

0 голосов
/ 27 июля 2011

В прошлом я делал нечто подобное, когда передавал строку, а затем разделял значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...