5

我可以做这样的事情吗?

[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

4 回答 4

3

答案很简单——是的!当您有自定义逻辑将值绑定到参数时,这就是您应该做的。您甚至可以使用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
}
于 2011-08-03T20:00:27.783 回答
0

我过去做过类似的事情,我传递了一个字符串然后拆分值。

于 2011-07-26T20:18:38.100 回答
0

我想说的答案是:是的!在您的评论中,您担心可能会导致麻烦的“许多其他问题”。在不知道您的想法的情况下,很难为您提供帮助。但是你所做的正是模型活页夹的设计目的。并且没有理由,为什么你应该每个动作只有一个对象。

于 2011-08-03T19:53:59.303 回答
0

我真的对 ASP.NET MVC 模型绑定需要我跳过以获得一些基本的反序列化的箍感到失望。

由于模型绑定远没有我对复杂模型/视图模型所希望的那么透明,所以我只是构建了一个自定义 ActionFilter 来解析我想在 action 方法中反序列化的类型 [和仅类型],并为我的所有操作使用ServiceStack.Text序列化/反序列化需求。

看看这里:

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

于 2011-08-07T05:16:04.393 回答