2012-08-01 10 views
6

私は、既存のJSON APIをハッキーMVC3実装から最新のMVC4 Web APIに変換することを検討しています。 MVC3の実装では、JSON.NETを使用してすべてのシリアライゼーションを行い、アップグレードをすばやくスムーズにします。アクションを呼び出すASP Web API Jsonのシリアル化をカスタマイズする

私は、何らかのアクションの結果がどのようにシリアライズされるかをカスタマイズしています。たとえば、出力オブジェクトのいくつかのプロパティだけを返すアクションと、かなり深いシリアル化を行うものがあります。私の現在の実装では、アクションは、HttpContextの適切な設定を設定することによって一連のシリアル化のオーバーライドを追加できます。これらは、後でJsonResultから派生したクラスを通してカスタムシリアル化のために取り上げられます。カスタムJsonConvertersを追加する主な用途は、シリアル化されるキー/値の数を制御および削減し、アクションに応じてシリアル化するようにパラメータを変更することです(特定のアクションは他のものより多くのオブジェクトパラメータを返す必要があります)。私は設定から​​JSONフォーマッタを取得し、世界的にシリアライズを変化させることができることを見るのWeb APIで

public class TestController : JsonController { 
    public JsonResult Persons() { 
     ControllerContext.HttpContext.Items[typeof(IEnumerable<JsonConverter>)] = new JsonConverter[] { 
      new InterfaceExtractorJsonConverter<IPersonForList>(), 
      new StringEnumConverter() 
     }; 

     ControllerContext.HttpContext.Items[typeof(IContractResolver)] = new SpecialCamelCasePropertyNamesContractResolver(); 
    } 
} 

public class JsonNetResult : JsonResult { 
    public override void ExecuteResult(ControllerContext context) { 
     var response = context.HttpContext.Response; 

     var additionalConverters = context.HttpContext.Items[typeof(IEnumerable<JsonConverter>)] as IEnumerable<JsonConverter> ?? Enumerable.Empty<JsonConverter>(); 

     var contractResolver = context.HttpContext.Items[typeof(IContractResolver)] as IContractResolver ?? new JsonContractResolver(); 

     var typeNameHandling = TypeNameHandling.None; 
     if (context.HttpContext.Items.Contains(typeof(TypeNameHandling))) 
      typeNameHandling = (TypeNameHandling)context.HttpContext.Items[typeof(TypeNameHandling)]; 

     response.Write(JsonConvert.SerializeObject(Data, Formatting.Indented, new JsonSerializerSettings { 
      ContractResolver = contractResolver, 
      ReferenceLoopHandling = ReferenceLoopHandling.Ignore, 
      Converters = additionalConverters, 
      TypeNameHandling = typeNameHandling 
     })); 
    } 
} 

:コントローラと私の現在のMVC3の実装では、JSONのシリアル化を制御するクラスの

コンデンス例。

var config = new HttpSelfHostConfiguration("http://localhost:8080"); 

var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().Single(); 

jsonFormatter.SerializerSettings.ContractResolver = new SpecialCamelCasePropertyNamesContractResolver(); 
jsonFormatter.SerializerSettings.Converters = new[] { new InterfaceExtractorJsonConverter<ITesting>() }; 

しかし、私は使用するJsonConverter's指定するために、いくつかの属性を追加することによって、個別(又はコントローラごと)にアクションのシリアル化を制御することを計画しました。したがって、私はJsonシリアライザに、呼び出されたアクション/コントローラに与えられた関連する属性を見つけてそれに応じてシリアル化を変更したいと思います。私はどこでどのようにこれを行うか分からない。私はJsonMediaTypeFormatterから継承し、何らかの形でそこで仕事をするべきですか?その他の選択肢は何ですか?

答えて

2

このようにしてシリアル化を制御したい人はいなかった。

class JsonNetFormatter : MediaTypeFormatter { 
    public override bool CanWriteType(Type t) { 
     return typeof(JsonNetResponse).IsAssignableFrom(t); 
    } 
    // TODO WriteToStreamAsync which is basically a copy of your original JsonNetResult 
} 
:これらのオブジェクトを扱うことができるよりも

class JsonNetResponse { 
    public IContractResolver ContractResolver { get;set; } 
    // Other Json.Net bits 
    public object Value { get; set; } 
} 

は、私は、カスタムフォーマッタを作成します。しかし、リワークの最小限の量とあなたの目標を達成するために、私が直接あなたの方法から、その情報のすべてを返します

関連する問題