2012-12-01 15 views
12

Chcę zastąpić domyślną serializację WCS JSON (dla wszystkich typów danych) za pomocą JSON.NET. Przeszukałem całą sieć i nie mogłem znaleźć działającego rozwiązania.Zamień domyślny serializator JSON w WCF 4 na JSON.NET

To mój przedmiot:

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

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

To jest moja funkcja WCF:

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

Jest to kod w 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))); 

     } 

To Web.Config :

<endpointBehaviors> 
    <behavior name="Behavior_Brands"> 
     <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Bare" /> 
    </behavior> 
    </endpointBehaviors> 

i sekcja usługi:

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

I wreszcie, to co ja dostaję przy uruchamianiu URL:

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

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

JSON odpowiedź oczywiście ignoruje Atrybuty JSON.NET.

Odpowiedz

16

W każdym razie, wymyśliłem sposób na użycie innego serializera, ręcznie, wydaje się, że jest bardziej wydajny i szybszy, ponieważ nie przechodzi przez serializator firmy Microsoft, chociaż jest mądrzejszy pod względem kodu.

  1. Ustaw wszystkie rodzaje zwrotów jak „System.ServiceModel.Channels.Message” w interfejsy i klasy ich realizacji.

    [OperationContract] 
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)] 
    System.ServiceModel.Channels.Message GetData(); 
    
  2. Utwórz metodę rozszerzenia więc można łatwo zbudować strumień pamięci z obiektu, za pomocą serializatora Json.NET (lub cokolwiek chcesz używać).

    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. W ciele metody badaniem, zwróci obiekt odcinkach bezpośrednio do strumienia

    return yourObject.GetJsonStream(); 
    
+4

Jakie są wyniki badań, które wskazują na ciebie to jest zdecydowanie szybciej? Niestety dla mojego przypadku testowego (hierarchia obiektów 500KB) przy użyciu podobnych alternatywnych technik, wydaje się, że podwójny krok serializacji JSON.NET Kopiowanie tablicy _plus_ byte do UTF8 w jakiś sposób czyni ją droższą niż zwykły DataContractJsonSerializer. :-( – icelava

Powiązane problemy