5

Это мой первый вопрос, который я задаю на этом сайте, так что простите меня, если я что-то пропустил.JSON.NET CustomCreationConverter с вложенными объектами

У меня есть некоторые проблемы десериализации сложного графа объектов с использованием JSON.NET. Мой класс иерархии (упрощенно) следующим образом:

public abstract class BusinessObjectBase 
{ 
    protected BusinessObjectBase(SerializationContext context) 
    { 
    } 
} 

public class TestBusinessObject : BusinessObjectBase 
{ 
    protected TestBusinessObject(SerializationContext context) 
     : base(context) 
    { 
    } 

    public NestedObject InnerObject { get; set; } 
} 

public class NestedObject : BusinessObjectBase 
{ 
    protected NestedObject(SerializationContext context) 
     : base(context) 
    { 
    } 
} 

классы не имеют CTOR по умолчанию, но специальный заказ десериализации CTOR (рядом с другим общественным CTOR с параметрами), как показано в примере. Чтобы создать экземпляр я написал конвертер обычай создания так:

internal class BusinessObjectCreationConverter : CustomCreationConverter<BusinessObjectBase> 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(BusinessObjectBase).IsAssignableFrom(objectType) && !objectType.IsAbstract; 
    } 

    public override BusinessObjectBase Create(Type objectType) 
    { 
     var businessObject = objectType.CreateUsingDesrializationConstructor<BusinessObjectBase>(); 
     return businessObject; 
    } 
} 

Метод расширения CreateUsingDesrializationConstructor() ищет специального десериализации CTOR и создает экземпляр с помощью CTOR.

Я добавил к преобразователю моего Json.NET сериализатора Например:

public class NewtonsoftJsonSerializer : ISerializer 
{ 
    public NewtonsoftJsonSerializer() 
     : this(new JsonSerializer 
     { 
      TypeNameHandling = TypeNameHandling.Auto, 
      ObjectCreationHandling = ObjectCreationHandling.Replace, 
      PreserveReferencesHandling = PreserveReferencesHandling.Objects, 
      ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor, 
      DefaultValueHandling = DefaultValueHandling.Ignore, 
      ContractResolver = new KsJsonContractResolver() 
     }) 
    { 
     this.serializer.Converters.Add(new BusinessObjectCreationConverter()); 
    } 

    public T Deserialize<T>(Stream stream) 
    { 
     T result; 
     using (var streamReader = new StreamReader(stream, Encoding.UTF8, true, BufferSize, true)) 
     using (var jsonReader = new JsonTextReader(streamReader)) 
     { 
      result = this.serializer.Deserialize<T>(jsonReader); 
     } 

     return result; 
    } 
} 

Когда я десериализация TestBusinessObject я могу видеть из отладчика, что преобразователь задать для каждого типа, является ли он в состоянии создать instance: TestBusinessObject, NestedObject и многие другие типы. Но моему конвертеру требуется только создать новый экземпляр TestBusinessObject, он NOT попросил создать вложенный экземпляр NestedObject, что я ожидал, и что мне очень нужно, поскольку в десериализации ctor есть некоторая проводная логика.

Что я здесь делаю неправильно, как сказать JsonSerializer использовать конвертер для каждого объекта даже для объекта root (верхнего уровня)?

EDIT: Думает становится более еще более сложным, когда экземпляр BusinessObjectBase содержится в объекте, что печатает я не знаю. В этом случае я также хочу, чтобы конвертер был вызван.

Спасибо заранее, Карстен

+0

Можете ли вы прояснить реальный быстро; вы создаете только объект внешнего уровня и хотите также вложенные объекты, или вы создаете объект внешнего уровня плюс вложенные и только хотите объект внешнего уровня? Я думаю, что вы сможете решить эту проблему без использования пользовательского сериализатора в зависимости от вашего ответа. – evanmcdonnal

+0

Конвертер создает только внешний объект уровня. Я хочу, чтобы объект внутреннего уровня создавался вторым вызовом конвертера. – CGR

+0

Я забыл упомянуть еще одну ситуацию: объект BusinessObjectBase может быть внутренним объектом non BusinessObjectBase. В этом случае, конечно же, должен быть вызван конвертер создания. – CGR

ответ

0

Try, чтобы дать [DataContract] атрибуты классов, которые вы хотите сериализовать или десериализации, а также убедитесь, что данные, которые вы имеете в этих классах они также имеющих этот атрибут. например.

[DataContract] 
public class TestBusinessObject : BusinessObjectBase 
{ 
    protected TestBusinessObject(SerializationContext context) 
     : base(context) 
    {{ 
    } 

    public NestedObject InnerObject { get; set; } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^