这基本上是问题Newtonsoft Object → Get JSON string的后续内容。
我有一个看起来像这样的对象:
[JsonConverter(typeof(MessageConverter))]
public class Message
{
public Message(string original)
{
this.Original = original;
}
public string Type { get; set; }
public string Original { get; set; }
}
我的要求是在初始化时将原始JSON字符串存储为对象的一部分。我已经能够(部分)使用自定义JsonConverter
成功实现此功能,然后基本上在JsonConverter
执行此类操作:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == Newtonsoft.Json.JsonToken.Null)
return null;
JObject obj = JObject.Load(reader);
return new Message(obj.ToString(Formatting.None))
{
Type = obj["type"].ToString()
};
}
然而,我遇到的问题是当我尝试从Message
继承类似
public class CustomMessage : Message
{
public string Prop1 { get; set; }
}
由于显而易见的原因,我的代码失败了,因为它尝试返回新的Message()
而不是新的CustomMessage()
。
没有用我的所有子类型实现一个大的if语句,并使用类似JObject["prop"].ToObject<T>()
之类的东西手动绑定,如何在仍使用所有子类型值绑定的同时成功填充Original
属性默认的反序列化?
注意:执行此操作的原因是因为原始邮件可能包含实际上未绑定的数据,因此我无法添加将对象序列化为的属性它代表着。
答案 0 :(得分:1)
以下解决方案
您可以做的一件事是按通用JsonConverter
属性装饰每个子类。
[JsonConverter(typeof(MessageConverter<Message>))]
public class Message
{
public Message(string original)
{
this.Original = original;
}
public string Type { get; set; }
public string Original { get; set; }
}
[JsonConverter(typeof(MessageConverter<CustomMessage>))]
public class CustomMessage : Message
{
public CustomMessage(string original) : base(original)
{
}
public string Prop1 { get; set; }
}
public class MessageConverter:JsonConverter其中T:Message { public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer) { throw new NotImplementedException(); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == Newtonsoft.Json.JsonToken.Null)
return null;
JObject obj = JObject.Load(reader);
var customObject = JsonConvert.DeserializeObject<T>(obj.ToString(), new JsonSerializerSettings
{
ContractResolver = new CustomContractResolver()
});
customObject.Original = obj.ToString();
return customObject;
}
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
}
//This will remove our declared Converter
public class CustomContractResolver : DefaultContractResolver
{
protected override JsonConverter ResolveContractConverter (Type objectType)
{
return null;
}
}
然后您可以为所有子类使用相同的序列化程序
CustomMessage x = JsonConvert.DeserializeObject<CustomMessage>("{\"type\":\"Test\",\"Prop1\":\"Prop1\"}");
Message y = JsonConvert.DeserializeObject<Message>("{\"type\":\"Test\"}");
答案 1 :(得分:1)
我打开这个问题,希望有人提出更好的答案,但我暂时使用以下解决方案来解决我的问题。
public static class MessageExtensions
{
public static T Deserialize<T>(this string message) where T : Message
{
T instance = Activator.CreateInstance<T>();
instance.Original = message;
JsonConvert.PopulateObject(message, instance);
return instance;
}
}