2012-12-01 3 views
12

にWCF 4でデフォルトJSONシリアライザを交換してください。 ネット全体を検索したところ、解決策が見つかりませんでした。は、私がJSON.NETでシリアライズを(すべてのデータ型の)デフォルトWCF JSONを交換したいJSON.NET

これは私の物である:

[JsonObject] 
public class TestObject 
{ 
    [JsonProperty("JsonNetName")] 
    public string Name = "John"; 

    [JsonProperty] 
    public DateTime Date = DateTime.Now; 
} 

これは私のWCF機能です:

[OperationContract] 
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)] 
    List<TestObject> Get(); 

これは、Global.asaxの中のコードです:

 protected void Application_Start(object sender, EventArgs e) 
    { 
     // Create Json.Net formatter serializing DateTime using the ISO 8601 format 
     var serializerSettings = new JsonSerializerSettings(); 

     serializerSettings.Converters.Add(new IsoDateTimeConverter()); 
     serializerSettings.Converters.Add(new BinaryConverter()); 
     serializerSettings.Converters.Add(new JavaScriptDateTimeConverter()); 
     serializerSettings.Converters.Add(new BinaryConverter()); 
     serializerSettings.Converters.Add(new StringEnumConverter()); 

     var config = HttpHostConfiguration.Create().Configuration; 

     Microsoft.ApplicationServer.Http.JsonMediaTypeFormatter jsonFormatter = config.OperationHandlerFactory.Formatters.JsonFormatter; 

     config.OperationHandlerFactory.Formatters.Remove(jsonFormatter); 

     config.OperationHandlerFactory.Formatters.Insert(0, new JsonNetMediaTypeFormatter(serializerSettings)); 

     var httpServiceFactory = new HttpServiceHostFactory 
     { 
      OperationHandlerFactory = config.OperationHandlerFactory, 
      MessageHandlerFactory = config.MessageHandlerFactory 
     }; 

     //Routing 
     RouteTable.Routes.Add(
      new ServiceRoute(
       "Brands", httpServiceFactory, 
       typeof(Brands))); 

     } 

これはのWeb.Configであります:

​​3210

やサービスセクション:

<service name="TestApp.CoreWCF.Brands"> 
    <endpoint address="" behaviorConfiguration="Behavior_Brands" binding="webHttpBinding" contract="TestApp.CoreWCF.IBrands"> 
     <identity> 
     <dns value="localhost" /> 
     </identity> 
    </endpoint> 
    </service> 

そして最後に、これはURLを起動するとき、私は取得していますものです:

"http://localhost:30000/Brands/Get"

[{"Date":"\/Date(1354364412708+0200)\/","Name":"John"}, {"Date":"\/Date(1354364412708+0200)\/","Name":"John"}] 

JSONの答えは明らかに無視しますJSON.NETの属性。コードが賢明それはビットメシエだが、それは、Microsoftのシリアライザを通過しないので、

答えて

16

はとにかく、私は別のシリアライザを使用する方法を考え出し、手動で、その方が効率的かつ迅速に思えます。

  1. すべての戻り値の型を、それらを実装するインターフェイスおよびクラスの "System.ServiceModel.Channels.Message"として設定します。

    [OperationContract] 
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)] 
    System.ServiceModel.Channels.Message GetData(); 
    
  2. あなたは簡単にJSON.NETシリアライザ(またはどちらか使用したい)を使用して、オブジェクトのうち、メモリストリームを構築することができるように拡張メソッドを作成します。ストリームに直接シリアライズ

    方法の体内に
    public static System.ServiceModel.Channels.Message GetJsonStream(this object obj) 
    { 
        //Serialize JSON.NET 
        string jsonSerialized = JsonConvert.SerializeObject(obj); 
    
        //Create memory stream 
        MemoryStream memoryStream = new MemoryStream(new UTF8Encoding().GetBytes(jsonSerialized)); 
    
        //Set position to 0 
        memoryStream.Position = 0; 
    
        //return Message 
        return WebOperationContext.Current.CreateStreamResponse(memoryStream, "application/json"); 
    } 
    
  3. 、オブジェクトを返す

    return yourObject.GetJsonStream(); 
    
+4

あなたにそれは間違いなく速いであることを示す検査結果は何ですか?残念ながら、同様の代替技術を使用している私のテストケース(500KBのオブジェクト階層)では、JSON.NETのシリアライゼーション_plus_バイト配列をUTF8にコピーするという2つのステップが、単純なDataContractJsonSerializerよりも高価になっています。 :-( – icelava

関連する問題