es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El equivalente programático de Json.NET para decorar una clase que implementa IEnumerable con el atributo JsonObject sería el siguiente: [JsonObject] public class MiClaseEnumerable : IEnumerable { … }

Estoy tratando de (des)serializar una clase compleja que, entre otras cosas, contiene un miembro que tiene una clase de tipo que implementa IEnumerable.

public class ClassToSerialize { public IEnumerableClass Foo; }
public class IEnumerableClass: IEnumerable<Bar> { ... }

La serialización funciona perfectamente. Al deserializar, obtengo una excepción de “Newtonsoft.Json.JsonSerializationException: ‘Cannot create and populate list type”. La solución normal sería decorar IEnumerableClass con [JsonObject] (según esta respuesta). El problema es que no tengo acceso al código de la clase, por lo que necesito una solución desde el propio (de)serializador. He intentado crear un resolvedor de contratos personalizado, pero hasta ahora no he tenido éxito.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para resolver este problema sin acceder al código de la clase, puedes crear un JsonConverter personalizado para manejar la deserialización de IEnumerableClass.

    Primero, crea una nueva clase que herede de JsonConverter y reemplace los siguientes métodos:

    • CanConvert: para indicar que el convertidor puede manejar el tipo IEnumerableClass.
    • ReadJson: para deserializar el JSON en el objeto IEnumerableClass.
    • WriteJson: para serializar el objeto IEnumerableClass en JSON.

    Aquí tienes un ejemplo de implementación:

    public class IEnumerableClassConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(IEnumerableClass);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            // Deserializa el JSON en una lista de objetos Bar
            var barList = serializer.Deserialize<><bar>>(reader);
    
            // Crea un nuevo objeto IEnumerableClass y poblarlo con la lista de Bar deserializada
            var enumerableClass = new IEnumerableClass();
            foreach (var bar in barList)
            {
                enumerableClass.Add(bar);
            }
    
            return enumerableClass;
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Serializa el objeto IEnumerableClass en una lista de objetos Bar
            var enumerableClass = (IEnumerableClass)value;
            var barList = enumerableClass.ToList();
    
            // Escribe la lista serializada en el flujo de JSON
            serializer.Serialize(writer, barList);
        }
    }
    

    Luego, al deserializar tu objeto JSON, registra este convertidor en el objeto JsonSerializerSettings:

    var settings = new JsonSerializerSettings();
    settings.Converters.Add(new IEnumerableClassConverter());
    
    var myObject = JsonConvert.DeserializeObject<classtoserialize>(json, settings);
    

    Esto te permitirá deserializar la clase compleja que contiene el miembro IEnumerableClass sin necesidad de modificar el código de la clase.

Comments are closed.