2012-04-10 32 views
5

だから、とhereのようないくつかの人々は、のMVC4モデルバインディングをApiControllersにバインドしているようですが、私が見ている問題は解決していないようです。MVC4でカスタムモデルバインダーを呼び出すにはどうすればよいですか?

私が本当にやりたいことは、整数リストの配列バインディングの動作を変更することです。だから私はこのような要求タイプを持っていたと言う:

public class MyRequestModel 
{ 
    public List<long> ListOfIntegers { get; set; } 

    ... 
} 

そして、このようなAPIのGETメソッド:

public ResultsResponseModel Get(MyRequestModel request) 
{ 
    // use request.ListOfIntegers meaningfully 

    ... 

    return response; 
} 

私は基本的に/api/results/?listOfIntegers=1+2+3+4+5を言うとList<long>プロパティにその決意を持ってできるようにしたいです。

私は通常のモデルバインディングトリックを試しましたが、MVC4のほとんどのWeb APIと同様に、モデルバインドのための完全に別個のパスがあるようです。

私はMyRequestModelSystem.Web.Http.ModelBinding.ModelBinder属性を使用して、そしてSystem.Web.Http.ModelBinding.IModelBinder「実装」というモデルバインダーを作成してもらいました遠いです。これは、コードに決して触れないスタックトレースを持つオブジェクト参照例外を一貫して生成します。

誰でもこれを打つ?次は何をしようか考えていますか?

UPDATE:ここで私は私のカスタムExceptionFilterAttributeで撮影してきたスタックトレースがあります:あなたがApiControllersを話しているなら、あなたは今、MVCのウェブAPIでバインドをモデル化し、しようとしている

Object reference not set to an instance of an object. 
    at System.Web.Http.ModelBinding.DefaultActionValueBinder.BindParameterValue(HttpActionContext actionContext, HttpParameterBinding parameterBinding) 
    at System.Web.Http.ModelBinding.DefaultActionValueBinder.<>c__DisplayClass1.BindValuesAsync>b__0(RequestContentReadKind contentReadKind) 
    at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass38.<ToAsyncVoidTask>b__37() 
    at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken) 
+0

あなたはスタックトレースを提出できますか? – jorgehmv

+0

スタックトレースを追加しました。 –

答えて

4

はここでここでサンプルモデルバインダー

public class MyRequestModelBinderProvider : ModelBinderProvider 
    { 
     MyRequestModelBinder binder = new MyRequestModelBinder(); 
     public IdeaModelBinderProvider() 
     {   
     } 

     public override IModelBinder GetBinder(HttpActionContext actionContext, ModelBindingContext bindingContext) 
     { 
      if (bindingContext.ModelType == typeof(MyRequestModel)) 
      { 
       return binder; 
      } 

      return null; 
     } 
    } 

のカスタムモデルバインダープロバイダー

を登録する例です210
IEnumerable<object> modelBinderProviderServices = GlobalConfiguration.Configuration.ServiceResolver.GetServices(typeof(ModelBinderProvider)); 
List<Object> services = new List<object>(modelBinderProviderServices); 
services.Add(new MyRequestModelBinderProvider()); 
GlobalConfiguration.Configuration.ServiceResolver.SetServices(typeof(ModelBinderProvider), services.ToArray()); 

は、今すぐあなたのカスタムモデルバインダーであなたは、クエリ文字列が

public class MyRequestModelBinder : IModelBinder 
    { 
     public MyRequestModelBinder() 
     { 

     } 

     public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
     { 
      MyRequestModel yourModel; 
      //use contexts to access query string values 
      //create/update your model properties 

      bindingContext.Model = yourModel; 
      //return true || false if binding is successful 
     } 

値にアクセスするためにコンテキストを使用あなたはWebAPIのではなく、MVCのためのクラスとインタフェースを使用していることを確認してください。いくつかの名前は同じですが、異なる名前空間とDLLです

+0

OKだから、適切な構造が整っていると思います。既定のWeb APIモデルバインディングを呼び出し、モデルバインダー内のリスト値パラメーターを手動で制御する方法があるかどうかは分かりますか? –

+0

カスタムModelBinderProvideのbase.GetBinderを呼び出して、デフォルトのモデルバインダーを取得し、それをカスタムモデルバインダーのプライベートフィールドに入れて、モデルバインダーから使用することができます。 –

+0

@FrancescoAbbruzzese私はそのようなことをしたいと思います。残念ながら、抽象クラスGetBinderメソッドを持つ抽象クラスであるModelBinderProviderを継承しているので、デフォルトのものはありません。私は 'System.Web.Http.Modelbinding.ModelBinders'の型からインスタンス化を送信しようとしましたが、大したことはありません。他のアイデア? –

関連する問題