2012-09-19 9 views
6

Voglio impostare un serializzatore di contratto solo per determinati tipi nella mia applicazione API Web ASP.NET. Posso configurare le impostazioni a livello globale nei App_Start/FormatterConfig.cs come questo:Come impostare Json.NET ContractSerializer per un determinato tipo specifico anziché globale?

public static void RegisterGlobalFormatters(MediaTypeFormatterCollection formatters) 
{ 
    jsonSerializerSettings.ContractResolver = new CriteriaContractResolver(new List<string>(new string[]{"mdData", "name", "label"})); 

...

ma come posso solo applicare questo a uno o più tipi specifici di classe?

Il motivo che voglio fare questo è perché ho bisogno di essere in grado di impostare quali campi devono essere serializzati in fase di esecuzione in base alla configurazione o parametri per il servizio web simile a questi esempi:

Using JSON.net, how do I prevent serializing properties of a derived class, when used in a base class context?

http://json.codeplex.com/discussions/347610

risposta

1

ho finito per usare un JsonConverter che solo scrive i parametri che sono specificati nell'elenco "Proprietà". È più basso di un ContractResolver o di un formattatore, ma non penso sia possibile configurarne uno per un tipo specifico.

public class ResourceConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(Resource)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     List<string> properties = new List<string>(new string[] { "Name", "Label" }); 

     writer.WriteStartObject(); 
     foreach (MemberInfo mi in value.GetType().GetMembers(BindingFlags.GetField | BindingFlags.Instance | BindingFlags.Public)) 
     { 
      PropertyInfo p = mi as PropertyInfo; 

      if (p != null && p.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Length == 0 && properties.Contains(p.Name)) 
      { 
       writer.WritePropertyName(p.Name); 
       serializer.Serialize(writer, p.GetValue(value, new object[] { })); 
      } 
     } 
     writer.WriteEndObject(); 
    } 
} 

questo può essere applicato a una classe con l'attributo:

[JsonConverter(typeof(ResourceConverter))] 

Questo mi sembra un hack, però, penso che dovrei usare il resolver contratto per ottenere l'elenco di immobili da serializzare, invece di usando direttamente la riflessione, ma non sono sicuro di come.

4

avete alcune opzioni:

  • creare un tipo personalizzato che viene gestito da un formatt personalizzato ER. Questo tipo personalizzato potrebbe specificare (in qualche modo) quali campi devono essere serializzato (e che le informazioni poi inseriti in un serializzatore JSON)
  • Guardate per controller configurazione (vedi here) per cercare di impostare il formattatore come requried
+0

La prima opzione mi ha portato a creare un JsonConverter personalizzato che è più basso di un formattatore ma non sono riuscito a capire come specificare un formattatore per un tipo particolare. – Rn222

0

vorrei provare a creare qualcosa di simile

public class MyJsonFormatter : JsonMediaTypeFormatter 
    { 
     public override bool CanWriteType(Type type) 
     { 
      return type == typeof(MyClass); 
     } 
    } 

e quindi inserire questo in l'inizio della raccolta formattatori

+0

Sembra scegliere solo il formattatore una volta per richiesta in base al tipo di oggetto radice che viene serializzato. Non funzionerà nel mio caso perché ho un oggetto wrapper a cui non voglio applicare le impostazioni. – Rn222

Problemi correlati