[英]Select type to use for deserialization in System.Text.Json
我有一個 .NET 6 應用程序需要反序列化一些 JSON 數據到 C# 對象,使用System.Text.Json
但是,在我試圖反序列化的類中,我有一個經典案例,其中屬性具有基類類型,如下所示:
public class ClassToDeserialize
{
public JobBase SomeJob { get; set; }
}
public class JobBase
{
public string JobName { get; set; }
}
需要反序列化為正確的派生類型,例如:
public class OnDemandJob : JobBase
{
public string RequestUser { get; set; }
}
public class ScheduledJob: JobBase
{
public string Schedule { get; set; }
}
我想做的是編寫一個自定義轉換器,它檢查 JSON 數據以決定使用哪種類型進行反序列化(例如,在上面的示例中,我們可以通過檢查是否存在實際的ScheduledJob
數據中的Schedule
屬性),然后反序列化為該類型。
現在,閱讀官方文檔,我很高興地發現微軟想到了這一點,並且有一篇文章,其中包含一個關於如何使用轉換器實現此場景的示例:
但是我的問題是這樣的:對我來說,他們在示例中實現的轉換器對於它需要做的事情來說似乎過於復雜。 特別是,他們在找到正確的類型后所做的是“手動”通過創建實例並手動讀取 JSON 數據並將屬性一個接一個地分配給 ZA8CFDE6331BD59EB2AC96F8911C4B666 來“手動”構建正確的派生 object。
對於我想要實現的目標,這似乎需要大量的手動工作。 直覺上,我認為應該可以做這樣的事情(偽代碼):
public JobBase Read(...)
{
if(jsonObject.HasProperty("Schedule")
{
return JsonSerializer.Deserialize<ScheduledJob>(jsonString);
}
else
{
return JsonSerializer.Deserialize<OnDemandJob>(jsonString);
}
}
這樣的事情可能嗎? 還是我真的必須逐個字段手動構建整個 object?
感謝@dbc 為我指明了正確的方向,這是我最終得到的轉換器:
public class JobBaseConverter : JsonConverter<JobBase>
{
public override JobBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
using (var jsonDocument = JsonDocument.ParseValue(ref reader))
{
if (jsonDocument.RootElement.TryGetProperty(nameof(ScheduledJob.Schedule), out var typeProperty))
{
return JsonSerializer.Deserialize<ScheduledJob>(jsonObject, options);
}
else
{
return JsonSerializer.Deserialize<OnDemandJob>(jsonObject, options);
}
}
}
public override void Write(Utf8JsonWriter writer, JobBase value, JsonSerializerOptions options)
{
if(value is ScheduledJob)
{
JsonSerializer.Serialize(writer, value as ScheduledJob, options);
}
else
{
JsonSerializer.Serialize(writer, value as OnDemandJob, options);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.