Json.NET - 如何使用内部构造函数序列化外部类?

时间:2015-07-20 07:39:08

标签: c# oop serialization json.net private-constructor

我需要序列化一个不能更改其源代码的类(将其视为事实),并且它来自不同的程序集。它只有一个构造函数

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

JsonConvert.SerializeObject(object)因此失败了。我想知道是否有办法使用Json.NET来序列化这个类,而不必添加代码甚至标签。

3 个答案:

答案 0 :(得分:5)

如果您有无参数构造函数,则应该可以通过添加以下设置来执行此操作:

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

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

问题编辑后更新:

如果你没有任何 public构造函数并且你没有无参数构造函数,那么我只知道2个选项:

  1. [JsonConstructor]属性添加到internal构造函数中(由于您无法编辑该类,这似乎不是您的选项)。
  2. 创建一个具有相似属性的代理类(不是优雅但不需要更改所需的类)。

答案 1 :(得分: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);
    }
}

答案 2 :(得分: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);
    }
}