2016-10-10 6 views
7

Web APIプロジェクト用にIValueProviderの実装をいくつか作成しましたが、インタフェース上のContainsPrefixメソッドの目的について混乱しています。Web API IValueProviderインターフェイスのContainsPrefixメソッドの目的は何ですか?

ContainsPrefix方法は、この要約のコメントがあります

コレクションが、指定された接頭辞が含まれているかどうかを決定します。

ただし、この方法の概要は抽象的なものであり、その方法にどのような機能が提供されるのか、どのような機能がどのような機能を果たすのか説明しません。 prefixはアクションパラメータ名になりますか?アクション名?コントローラの名前は?これらのいずれかの最初の3文字? IValueProviderがどのアクションパラメータに値を提供すべきかを自動的に把握するためにこのメソッドが存在しますか?

私は私がWeb APIのCollectionModelBinder内の参照、MutableObjectModelBinderSimpleModelBinderProvider、およびCompositeValueProviderを参照してくださいんがContainsPrefix方法が私のIValueProvider実装でのWeb APIフレームワークによって呼び出さ見ることはありません。たとえば、次の実装は、私のテストでは、私に何の問題が発生していない:

MyValueProvider:

public class MyValueProvider : IValueProvider 
{ 
    public bool ContainsPrefix(string prefix) 
    { 
     throw new NotYetImplementedException(); 
    } 

    public ValueProviderResult GetValue(string key) 
    { 
     return new ValueProviderResult("hello", "hello", CultureInfo.InvariantCulture); 
    } 
} 

TestController:私のTestControllerから

public class TestController : ApiController 
{ 
    public string Get([ModelBinder]string input) 
    { 
     return input; 
    } 
} 

GET要求はハロー戻ります、だから私はGetValueが呼び出されていることを知っていますMyValueProviderですが、例外はスローされませんので、ContainsPrefixは呼び出されません。

  1. ContainsPrefixはいつWeb APIフレームワークから呼び出されると思いますか?
  2. このメソッドにはどのようなprefixが提供されますか?ここ

答えて

2

この(非常に重要な)メソッドが何をしているのかわからなくても、値プロバイダを作成できたのは奇妙です。 まず、プロバイダーの価値は何ですか?つまり、アクションで指定するパラメータの値を提供します。例:

public ActionResult Index(string test) { 

} 

ここでは、「test」という名前のパラメータを持つアクションがあります。その価値をどこで得るのか?バリュープロバイダーから。クエリ文字列やフォームデータプロバイダなど、いくつかのビルトインプロバイダがあります。これらのプロバイダは、プロバイダの一部が値を提供できるようになるまで、1つずつ呼び出されます。たとえば、クエリ文字列パラメータ "test"がある場合、クエリ文字列値プロバイダはそれを認識して値を返すので、他のプロバイダは呼び出されません。次に、ポストデータにパラメータ "test"が含まれている場合は、それが使用されます。

したがって、このパラメータ名(この場合は "test")はContainsPrefixと呼ばれます。たとえば、クエリ文字列値プロバイダを取ります。クエリ文字列に "test"が含まれていない場合 - このプロバイダのContainsPrefixは "false"を返し、次の値プロバイダが呼び出されます。 trueを返す場合、GetValueはvalueを返す必要があり、他のプロバイダは呼び出されません。

cookieからのパラメータの値を指定する場合は、ContainsPrefixメソッドで、指定された名前のCookieがあるかどうかを確認します。すべてのデフォルト値プロバイダが値を提供できない場合にのみ呼び出されることに注意してください。

したがって、TLDR:prefixは値を提供するパラメータ名を表します。

+1

これは意味があり、最初にインターフェイスを実装したときに疑うものです。しかし、実際には 'ContainsPrefix'がフレームワークによって呼び出されることはありません。説明するためにサンプルコードを少し追加して質問を更新しました。 –

+0

@CoreySmirtあなたは正しいです。 Web APIで使用されるデフォルトのモデルバインダーのうち、すべて(一部ではありません)は、GetValueを呼び出す前にContainsPrefixを呼び出しません(ソースコードを調べることで見つけました)。それは、予想される行動ではなく、それらのバインダーの作成者の監督だと思います。それにもかかわらず、上記の私はまだ有効ですが、私は使用されるはずだったContainsPrefixを実装するほうがよいでしょう。 – Evk

+1

Web APIフレームワークが 'ContainsPrefix'を呼び出す際に使用する*すべてのモデルバインダーがキーではないという事実がここにあります。 'string'のような単純な型の場合、' ContainsPrefix'は決して呼び出されません。 –

2

Pride Parrot How to create a custom session value provider物品

の部分はContainsPrefix方法は、値プロバイダが指定された接頭辞のデータを解決できるかどうかを を決定するために、モデルバインダーによって呼び出されています。あなたは 値プロバイダーとDefaultModelBinderチェックを結合モデルの時SessionValueProvider

public class SessionValueProvider: IValueProvider 
{ 
    public bool ContainsPrefix(string prefix) 
    { 
     return HttpContext.Current.Session[prefix] != null; 
    } 

    public ValueProviderResult GetValue(string key) 
    { 
     if(HttpContext.Current.Session[key] == null) 
      return null; 

     return new ValueProviderResult(HttpContext.Current.Session[key], 
      HttpContext.Current.Session[key].ToString(), CultureInfo.CurrentCulture); 
    } 
} 


public class UserModel 
{ 
    public string AccountNo { get; set; } 
    ... 
} 

public ViewResult SomeAction(UserModel userModel, ...) 
{ 
    ... 
} 

をお持ちの場合は

は、彼らがContainsPrefixメソッドを呼び出し ことにより、パラメータAccountNoの値を返すことができます。値プロバイダ 登録されたイヤラーのどれもが値を返すことができなかった場合、SessionValueProvider はセッションでこのようなパラメータが格納されているかどうかを確認し、そうであれば 値を返します。

関連する問題