0

パラメータのないアクションメソッドがあります。

QueryStringコレクションには私のすべての値が含まれています。のキーはQueryString、ビューモデルのプロパティと一致します。

var queryStringValueProvider = new QueryStringValueProvider(ControllerContext);
var providerResult = queryStringValueProvider.GetValue(ValidationKeys.Id); // ?!

var viewModelTypeName = queryString[ValidationKeys.ViewModelType];

var viewModelType = Type.GetType(viewModelTypeName);
var viewModelInstance = providerResult.ConvertTo(viewModelType); // throws an InvalidOperationException

QueryStringコレクションをビューモデルに変換するにはどうすればよいですか?ASP.NET MVCは、ビューモデルをアクションメソッドパラメーターに渡すだけで、すでにこれを実行しています。したがって、必要なのは、ASP.NETMVCメカニズムを使用した後でモデルをバインドすることです。

4

4 に答える 4

0

カスタムモデルバインディングを手動で行うには、カスタムモデルバインダー(実装IModelBinder)を作成し、それをIoCコンテナーに登録します。

this.UpdateModelまたは、アクションメソッド内で呼び出すこともできます。これにより、ValueProvider(RouteData、Request.FormコレクションおよびQueryString)からの値がモデルにバインドされます。

于 2012-06-21T15:36:56.547 に答える
0

あなたが求めているのはシリアル化です。これを簡単に行うために、QueryStringValueProviderを引数として受け入れるコンストラクターのオーバーロードを配置し、そのコンストラクターがプロバイダーに基づいてモデルのすべてのプロパティを初期化する役割を果たします。文字列に固執する場合は、そのようなコンストラクターを、すべてのモデルに継承できるモデル基本クラスに非常に簡単に配置できます。

これは拡張メソッドに組み込むこともできるため、構築時ではなく「オンデマンド」と呼ぶことができます。

于 2012-06-21T15:37:46.390 に答える
0

あなたが使うことができますTryUpdateModel

public ContentResult TestAction()
{
   var model = new MyModel();

   if(TryUpdateModel(model, new QueryStringValueProvider(ControllerContext)))
   {
      return Content("success");
   }

   return Content("failed");
}
于 2012-06-21T17:24:01.643 に答える
0

コントローラーのアクション

var viewModelTypeName = queryString[ValidationKeys.ViewModelType];
var viewModelType = Type.GetType(viewModelTypeName);
var instance = Activator.CreateInstance(viewModelType);
UpdateModelUsingQueryString(instance);

UpdateModel

protected internal void UpdateModelUsingQueryString<TModel>(TModel model) where TModel : class
{
    if (model == null) throw new ArgumentNullException("model");

    Predicate<string> propertyFilter = propertyName => new BindAttribute().IsPropertyAllowed(propertyName);
    var binder = Binders.GetBinder(typeof(TModel));

    var bindingContext = new ModelBindingContext()
    {
        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()),
        ModelState = ModelState,
        PropertyFilter = propertyFilter,
        ValueProvider = new QueryStringValueProvider(ControllerContext)
    };
    binder.BindModel(ControllerContext, bindingContext);
}

問題は、設計上機能しないUpdateModelかどうかでした。どちらの方法もを使用します。ただし、を使用する必要があります。TryUpdateModelobjecttypeof(TModel)model.GetType()

ご覧ください:モデルバインディング-外部アセンブリを入力

ダリン・ディミトロフは正しい答えを出しました:)

于 2012-06-22T08:56:13.700 に答える