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

Json.NET - how to serialize an external class with internal constructor?

我需要序列化一个 class ,它的源代码不能更改(把这个当作事实),它来自不同的程序集。它只有一个构造函数

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

JsonConvert.SerializeObject(object) 当然因此而失败。我想知道是否有一种方法可以使用 Json.NET 序列化此 class 而无需向其添加代码甚至标签。

如果你有一个无参数构造函数,你应该可以通过添加以下设置来做到这一点:

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

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

问题编辑后更新:

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

  1. [JsonConstructor] 属性添加到您的 internal 构造函数(在您的情况下这似乎不是一个选项,因为您无法编辑 class)。
  2. 创建一个具有类似属性的代理 class(不是那么优雅,但不需要更改 class)。

您可以使用具有类似属性的代理 class:

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

你应该使用 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);
    }
}