假设我有以下内容(我的实际代码的一个非常简化的版本;假设Wrapper
和C
有更多的成员没有显示):
interface I { }
class C : I
{
public string Name { get; set; }
}
class Wrapper
{
public I Instance { get; set; }
}
class Program
{
static void Main(string[] args)
{
Wrapper wrapper = new Wrapper
{
Instance = new C { Name = "Test" }
};
JsonSerializerSettings settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
};
Console.WriteLine(JsonConvert.SerializeObject(wrapper, Formatting.Indented, settings));
}
}
输出将包含Instance的类型信息,因为实际类型与其声明的类型不同,如预期的那样:
{
"Instance": {
"$type": "ConsoleApplication.C, ConsoleApplication",
"Name": "Test"
}
}
假设我使用JsonConverter
的自定义Wrapper
:
class WrapperConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Wrapper);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Wrapper wrapper = (Wrapper)value;
JObject root = new JObject();
JObject instance = JObject.FromObject(wrapper.Instance);
root.Add("Instance", instance);
root.WriteTo(writer);
}
}
这不再输出Instance的类型信息:
{
"Instance": {
"Name": "Test"
}
}
在Instance
中手动构建JObject
时,如何强制包含WrapperConverter.WriteJson
的类型信息?
答案 0 :(得分:2)
如果您将meta.getSQLStatementsString();
修改为:
WriteJson
它也会输出public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var wrapper = (Wrapper)value;
var root = new JObject();
var instance = JObject.FromObject(wrapper.Instance, new JsonSerializer
{
TypeNameHandling = TypeNameHandling.Objects
});
root.Add("Instance", instance);
root.WriteTo(writer);
}
属性。
答案 1 :(得分:1)
为了使用"$type"
为根对象发出TypeNameHandling.Auto
信息,您需要使用JsonSerializer.Serialize()
的一个重载,该重载具有预期的参数 root type:
JsonSerializer.Serialize(JsonWriter, Object, Type)
JsonSerializer.Serialize(TextWriter, Object, Type)
但是,正如您所注意到的,JObject.FromObject()
没有重载允许传递预期的根类型。因此,您将使用JTokenWriter
手动构建JObject
:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Wrapper wrapper = (Wrapper)value;
JObject root = new JObject();
using (var tokenWriter = new JTokenWriter())
{
serializer.Serialize(tokenWriter, wrapper.Instance, typeof(object));
root.Add("Instance", tokenWriter.Token);
}
root.WriteTo(writer);
}
您还可以通过跳过中间JObject
表示来提高性能:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Wrapper wrapper = (Wrapper)value;
writer.WriteStartObject();
writer.WritePropertyName("Instance");
serializer.Serialize(writer, wrapper.Instance, typeof(object));
writer.WriteEndObject();
}