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 个选项:
- 将
[JsonConstructor]
属性添加到您的 internal
构造函数(在您的情况下这似乎不是一个选项,因为您无法编辑 class)。
- 创建一个具有类似属性的代理 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);
}
}
我需要序列化一个 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 个选项:
- 将
[JsonConstructor]
属性添加到您的internal
构造函数(在您的情况下这似乎不是一个选项,因为您无法编辑 class)。 - 创建一个具有类似属性的代理 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);
}
}