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

答えはただのことだと思います:はい!あなたのコメントでは、問題を引き起こす可能性のある「他の多くの問題」について懸念しています。あなたが考えている問題を知らなければ、あなたを助けるのは難しいです。しかし、あなたが行ったことは、まさにモデルバインダーが設計されていることです。また、アクションごとにオブジェクトを1つだけにする必要がある理由はありません。

于 2011-08-03T19:53:59.303 に答える
0

ASP.NET MVC モデル バインドでは、基本的な逆シリアル化を取得するためにジャンプする必要があるという面倒なことに、私は本当にがっかりしました。

モデルバインディングは、複雑なモデル/ビューモデルに期待していたほど透過的ではなかったので、アクションメソッドで逆シリアル化し、すべての私のシリアライゼーション/デシリアライゼーションが必要です。

ここを見てください:

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

于 2011-08-07T05:16:04.393 に答える
0

過去に、文字列を渡してから値を分割するという同様のことをしました。

于 2011-07-26T20:18:38.100 に答える