2012-09-19 14 views
6

Quiero establecer un serializador de contratos solo para ciertos tipos en mi aplicación ASP.NET Web API. Puedo configurar los ajustes a nivel mundial en los App_Start/FormatterConfig.cs como este:Cómo configurar Json.NET ContractSerializer para un cierto tipo específico en lugar de globalmente?

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

...

pero ¿cómo puedo simplemente aplicar esto a uno o más tipos específicos de clase?

La razón por la que quiero hacer esto es porque tengo que ser capaz de establecer qué campos deben ser serializados en tiempo de ejecución basado en la configuración o parámetros para el servicio web similar a estos ejemplos:

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

Respuesta

1

terminé usando un JsonConverter que sólo escribe los parámetros que se especifican en la lista de "propiedades". Es más bajo que un ContractResolver o un formateador, pero no creo que sea posible configurar uno para un tipo específico.

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(); 
    } 
} 

Esto se puede aplicar a una clase con el atributo:

[JsonConverter(typeof(ResourceConverter))] 

Este parece ser un truco sin embargo, creo que debería utilizar el sistema de resolución de contrato para obtener la lista de propiedades para serializar en lugar de usando la reflexión directamente, pero no estoy seguro de cómo.

4

Usted tiene algunas opciones:

  • crear un tipo personalizado que es manejado por un formatt personalizada er. Este tipo personalizado podría especificar (de alguna manera) lo que necesitan campos para serializar (y que la información se introduce en un serializador JSON)
  • mirada a la configuración por controlador (ver here) para tratar de configurar el formateador como requried
+0

Su primera opción me llevó a crear un JsonConverter personalizado que tiene un nivel más bajo que un formateador pero no pude encontrar la manera de especificar un formateador para un tipo en particular. – Rn222

0

me gustaría tratar de crear algo como esto

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

y luego insertarlo en el comienzo de la colección formateadores

+0

Parece que solo elige el formateador una vez por solicitud en función del tipo de objeto raíz que se está serializando. No funcionará en mi caso porque tengo un objeto envoltorio al que no quiero aplicar la configuración. – Rn222

Cuestiones relacionadas