6

タイトルは多かれ少なかれそれをすべて言います。ルートごとに異なる動作をするようにJSONMediaTypeFormatterを構成しようとしています。

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

コントローラーにコードを入れて、リクエストがレガシールートと新しいルートのどちらで受信されたかを判断し、それに応じてフォーマッターを変更することができます。

必要に応じて、ActionFilterを使用してフォーマッターを変更することもできます。

ただし、ルートごとのレベルでフォーマッターを構成する方法があるかどうか疑問に思っていました。これは、APIの動作が異なる抽象化のレベルだからです。これは、ルート構成の時点またはデリゲートハンドラーのいずれかにあります。

助言がありますか?

4

1 に答える 1

7

あなたの 2 つの JSON がどのくらい違うのか、そしてそれらをどう扱っているのかは完全にはわかりませんが、私に尋ねられたら、フォーマッターでそれを行います。

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 をこれに置き換えます。

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

Web APIDelegatingHandlerでは、特定のルートでのみ実行することができますが、Formattersコレクションはグローバルであるため、実際には意味がありません。ルートスコープのハンドラーからでも実行時に変更する意味はありません。

于 2013-01-14T04:37:23.553 に答える