Sostituire default serializzatore JSON in WCF 4 a JSON.NET

Voglio sostituire a quello di default WCF JSON (per tutti i tipi di dati) di serializzazione con JSON.NET.
Ho cercato in tutta la rete e non riuscivo a trovare una soluzione di lavoro.

Questo è il mio oggetto:

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

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

Questo è il mio WCF funzione:

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

Questo è il codice Globale.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)));

      }

Questo è il Web.Config:

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

e la sezione servizi:

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

E, infine, questo è quello che mi sto avviando la URL:

http://localhost:30000/Brands/Get

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

La risposta JSON, ovviamente, ignora il JSON.NET attributi.

InformationsquelleAutor max2005b | 2012-12-01



One Reply
  1. 18

    Comunque, ho pensato a un modo per utilizzare un diverso serializzatore, manualmente, sembra più efficiente e più veloce perché non passa attraverso Microsoft serializzatore, se il codice wise è un po ‘ di messier.

    1. Impostare tutti i tipi di ritorno come “Sistema.ServiceModel.Canali.Messaggio” in Interfacce e classi di attuazione.

      [OperationContract]
      [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
      System.ServiceModel.Channels.Message GetData(); 
    2. Creare un metodo di estensione in modo che si può facilmente costruire un flusso di memoria di un oggetto, utilizzando il JSON.NET serializzatore (o a seconda di come si desidera utilizzare).

      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. Nel metodo del corpo, restituire l’oggetto serializzato direttamente nel flusso

      return yourObject.GetJsonStream();
    • Quali sono i risultati di test che indicano a voi è sicuramente più veloce? Purtroppo per il mio caso di test (500KB gerarchia di oggetti) utilizzando le stesse tecniche alternative, sembra il doppio passaggio di JSON.NET messa in serie più array di byte copia UTF8 in qualche modo rende più costoso di semplicemente DataContractJsonSerializer. 🙁

Lascia un commento