我目前正在一个API上做一些工作,在序列化它并返回JSON之前,我正在转换对象。我期望JSON结果是Cast对象而不是Uncast对象的结果,但是我从Uncast对象
中获得JSON中的所有属性示例代码using System;
using Newtonsoft.Json;
namespace JSONSerializationOfCastObject
{
class Program
{
static void Main(string[] args)
{
B InstanceB = new B(){PropA = "A",PropB = "B"};
A InstanceA = InstanceB;
var JSONInstanceA = JsonConvert.SerializeObject(InstanceA);
Console.WriteLine(JSONInstanceA);
Console.ReadLine();
}
}
public class A
{
public string PropA { get; set; }
}
public class B:A
{
public string PropB { get; set; }
}
}
结果{"PropB":"B","PropA":"A"}
预期结果
{"PropA":"A"}
另一个类型不是你期望的
的例子 B InstanceB = new B(){PropA = "A",PropB = "B"};
A InstanceA = InstanceB;
var x = InstanceA.GetType() == typeof(A); //==> False but we casted it to A
我只是想不明白,NewtonSoft必须在引擎盖下做一些反思。
GitHub示例:https://github.com/tharris29/JSONSerializationOfCastObject/tree/master
所以我理解这与反思有关,但这似乎是一个奇怪的结果。是否有一种方法可以告诉序列化程序要使用什么对象类型进行序列化?
仅仅因为您将B
分配给A
并不意味着它不再是B
。如果您在赋值后打印出InstanceA
变量的类型,您就可以自己看到这一点:
B instanceB = new B() { PropA = "A", PropB = "B" };
A instanceA = instanceB;
Console.WriteLine(instanceA.GetType().Name);
您将看到,结果是B
。
Json。Net使用反射来查看对象的实际类型并获取其所有属性。据我所知,它没有一个内置的方法来限制属性仅为基类型的属性。如果你想这样做,你需要一个自定义的JsonConverter
。这里有一个可能对你有用(注意它也使用了反射):
public class BaseTypeConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
T instance = (T)value;
JObject obj = new JObject();
foreach (PropertyInfo prop in typeof(T).GetProperties())
{
if (prop.CanRead)
{
obj.Add(prop.Name, JToken.FromObject(prop.GetValue(instance)));
}
}
obj.WriteTo(writer);
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
你可以这样使用这个转换器:
B instanceB = new B() { PropA = "A", PropB = "B" };
// serialize B, but only include the properties from type A
string json = JsonConvert.SerializeObject(instanceB, new BaseTypeConverter<A>());
Console.WriteLine(json);
输出:{"PropA":"A"}