2013-01-14 6 views
6

タイトルは多かれ少なかれすべてです。 JSON MediaTypeFormatterがルートごとに異なる動作をするように設定しようとしています。Web APIのルートフォーマッタ設定ごと

特に、WebAPIには同じコントローラにマップされている2つのルートがあります。 各ルートは同じ操作を実行し、同じデータを返しますが、既存のコンシューマとの後方互換性の理由から、出力をわずかに異なる形式にする必要があります。

コントローラーにコードを入力して、要求が従来のルートまたは新しいルートに入ったかどうかを判断し、それに応じてフォーマッターを変更することができます。

また、必要に応じてActionFilterを使用して書式を変更することもできます。

しかし、私のAPIが異なる振る舞いをする抽象レベルであるため、経路ごとのフォーマッタを設定する方法があるかどうかは疑問でした。これは、ルートコンフィグレーションまたは代行ハンドラのポイントにある可能性があります。

提案がありますか?

答えて

6

私はあなたの2 JSONsはどのように多くの異なる全くわからないとまさにあなたも一緒にやっている、しかし、あなたは私に言わせれば、私はフォーマッタでそれを行うだろう:

public class MyJsonMediaTypeFormatter : JsonMediaTypeFormatter 
{ 
    private IHttpRouteData _route; 

    public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, System.Net.Http.Headers.MediaTypeHeaderValue mediaType) 
    { 
     _route = request.GetRouteData(); 
     return base.GetPerRequestFormatterInstance(type, request, mediaType); 
    } 

    public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, HttpContent content, TransportContext transportContext) 
    { 
     if (_route.Route.RouteTemplate.Contains("legacy")) 
     { 
      //here set the SerializerSettings for non standard JSON 
      //I just added NullValueHandling as an example 
      this.SerializerSettings = new JsonSerializerSettings 
       { 
        NullValueHandling = NullValueHandling.Ignore 
       }; 
     } 

     return base.WriteToStreamAsync(type, value, writeStream, content, transportContext); 
    } 
} 

あなたはでしょうデフォルトのJsonMEdiaTypeFormatterをこのものに置き換えます。あなたが唯一の特定のルート上で動作しますが、Formattersコレクションがグローバルであるため、その実行時でさえroute-から変更するにはポイントがありませんので、それは本当に意味がないDelegatingHandlerを持つことができたWeb APIで

config.Formatters.RemoveAt(0); 
    config.Formatters.Insert(0, new MyJsonMediaTypeFormatter()); 

スコープ付きハンドラです。

+0

ええ、私はカスタムMediaTypeFormatterの使用を検討していました。上のあなたの例は私が達成しようとしているものと同じです。しかし、私は、ロジックを導入することによって、アプリケーションのロジックがかなりアプリケーションに依存しないものになることに懸念しています。私は知っている、あなたの解決策は確かに機能するだろう - しかし、私の純粋主義者は、私の懸念をよく、本当に分かち合うのが好きです。 –

+1

コントローラごとの設定(* IControllerConfiguration * http://blogs.msdn.com/b/jmstall/archive/2012/05/11/per-controller-configuration-in-webapi.aspx)を使用してこれを登録することができますそれが適用される1つのコントローラの "カスタム"フォーマッタのみ。このように、コアアプリケーションはデフォルトのフォーマッタを使用しますが、より多くの要件を持つコントローラは特定のフォーマッタを使用します。 –

+0

実際にアクションフィルタを使用する方法と実際にどのように違うのかは実際にはわかりません。実際には、IControllerConfiguration属性を使ってこれを達成できるかどうかわからないのは、ルート情報/要求コンテキスト情報にアクセスできないためです。 –

関連する問題