假设我有一个看起来像这样的JSON文档:
{
"Id" : "233124",
"RequestDate" : "2019-11-25T10:00:00"
"RequestPayload" : {
"Id" : "123abc",
"Url" : "http://blah.example/api/action",
"PostData" : "insert random post data here"
}
}
我有几个看起来像这样的C#POCO:
public class RequestLog {
public string Id { get; set; }
public DateTime RequestDate { get; set; }
public object RequestPayload { get; set; }
}
public class RequestPayload {
public string Id { get; set; }
public string Url { get; set; }
public string PostData { get; set; }
}
是否有一种方法让Json.Net反序列化文档,使得RequestLog.RequestPayload
属性的类型为RequestPayload
,即使它被声明为object
也是如此?目的是将其转换回RequestPayload
以便对其进行操作,如下所示:
var result = JsonConvert.DeserializeObject<RequestLog>(json, ...);
var requestPayload = (RequestPayload)request.RequestPayload;
// do other stuff with requestPayload here
我无法更改RequestLog
的声明,因为它位于我无法控制的NuGet包中。我研究过要创建一个自定义转换器,看来应该是可能的,但是我对如何实现它感到完全困惑。
答案 0 :(得分:3)
您可以为RequestLog
类使用自定义转换器:
public class RequestLogConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(RequestLog);
public override bool CanWrite => false;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
// Start by running the default serialisation
var log = new RequestLog();
serializer.Populate(jObject.CreateReader(), log);
// Manually deserialize RequestPayload
log.RequestPayload = jObject["RequestPayload"].ToObject<RequestPayload>();
return log;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
可用于以下用途:
JsonConvert.DeserializeObject<RequestLog>(json, new JsonSerializerSettings
{
Converters = new JsonConverter[] { new RequestLogConverter() }
});
答案 1 :(得分:1)
如果必须将RequestPayload
的{{1}}属性声明为RequestLog
,并且不需要此代码可重复使用,则可以强制使用此代码。
object
答案 2 :(得分:-1)
在您的RequestLog
类中,
更改:
public object RequestPayload { get; set; }
收件人:
public RequestPayload RequestPayload { get; set; }
然后您可以在反序列化之后使用它,而不必强制转换它:
var result = JsonConvert.DeserializeObject<RequestLog>(json, ...);
var requestPayload = result.RequestPayload;
// do other stuff with requestPayload here