2015-07-20 4 views
1

Мне нужно сериализовать класс, который его исходный код не может изменить (возьмите это как факт), и это из другой сборки. Она имеет только один конструкторJson.NET - как сериализовать внешний класс с помощью внутреннего конструктора?

public class MyObject 
    { 
     string _s; 
     int _i; 
     internal MyObject(string s, int i) 
     { 
      // ... 
     } 
    } 

JsonConvert.SerializeObject(object) терпит неудачу, конечно, из-за этого. Интересно, есть ли способ использовать Json.NET для сериализации этого класса, не добавляя к нему код или даже теги.

+1

Что такое сообщение об ошибке вы получаете, когда это не удается? Причина, о которой я прошу, не должен «DeserializeObject» бросать исключение, если он связан с конструктором, поскольку это когда он должен снова построить объект. –

+0

Является ли класс 'MyObject' закрытым? Можете ли вы наследовать его? –

+0

@MarioStoilov Это не запечатан. –

ответ

3

Если у вас есть конструктор без параметров а, вы должны быть в состоянии сделать это, добавив следующий параметр:

JsonSerializerSettings settings = new JsonSerializerSettings() 
{ 
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor 
}; 

var serializedJson = JsonConvert.DeserializeObject<MyObject>(jsonString, settings); 

Update после вопроса редактирования:

Если у вас нет любыеpublic конструкторы, и у вас нет конструктора без параметров, тогда я знаю только два варианта:

  1. Добавьте атрибут [JsonConstructor] в свой конструктор internal (который не выглядит в вашем случае, поскольку вы не можете отредактировать класс).
  2. Создайте прокси-класс со схожими свойствами (не такой элегантный, но без изменения требуемого класса).
+0

Привет, пожалуйста, прочитайте мой отредактированный пост –

+0

Предлагаемое решение не может быть использовано, потому что * исходный код не может быть изменен (принимайте это как факт) *, как было указано в вопросе. –

1

Вы можете использовать прокси-класс с аналогичными свойствами:

public sealed class TargetClass{ 
    public static readonly TargetClass tc = new TargetClass(); 
    public int Id; 
    public string SomeName; 
    private TargetClass(){ 
     this.Id=50; 
     this.SomeName="My, What Bastardry"; 
    } 
} 
public class ProxyClass{ 
    public int Id {get; set;} 
    public string SomeName {get; set;} 
    public ProxyClass(){ 
    } 
    public ProxyClass(int id, string somename){ 
     Id = id; 
     SomeName = somename; 
    } 
} 
public class Program 
{ 
    public static void Main() 
    { 
     TargetClass tgt = TargetClass.tc; 
     ProxyClass pc = new ProxyClass(tgt.Id,tgt.SomeName); 
     string s = JsonConvert.SerializeObject(pc); 
     Console.WriteLine(s); 
    } 
} 
+0

Привет, пожалуйста, прочитайте мой отредактированный пост. –

+1

Быстрый и грязный пример с использованием Reflection и прокси-объекта, но вы можете использовать его в сочетании с пользовательскими JsonConvertors, упомянутыми другими: https://dotnetfiddle.net/OtOXSm –

2

Вы должны использовать custom JsonConverter.

решение было бы что-то вроде

public class MyObjectProxy 
{ 
    public string s { get; set; } 
    public int i { get; set; } 
} 

public class MyObjectJsonConverter : JsonConverter 
{ 
    public override void WriteJson(
     JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     // Create an instance of MyObjectProxy, copy values from the 
     // instance of MyObject, write JSON from the MyObjectProxy. 
    } 

    public override object ReadJson(
     JsonReader reader, Type type, object value, JsonSerializer serializer) 
    { 
     // Deserialize MyObjectProxy, create an instance of MyObject, 
     // copy properties from the deserialized MyObjectProxy. 
    } 

    public override bool CanConvert(Type type) 
    { 
     return typeof(MyObject).IsAssignableFrom(type); 
    } 
} 
Смежные вопросы