System.Text.Json中JObject的等效项
c#
我有一个属性类型为 的 DTO 类JObject。此 DTO 类在多个服务之间通过 HTTP 发送/接收。使用 JObject 是因为ExtractedData它没有预定义的属性
public class MyDTO
{
public JObject ExtractedData {get;set;}
}
我正在将此项目转换为 .NET 5。什么相当于 .NET 5 中的 JObject?我试图避免 JsonDocument 因为(来自文档):
JsonDocument 将数据的内存视图构建到池化缓冲区中。因此,与 Newtonsoft.Json 中的 JObject 或 JArray 不同,JsonDocument 类型实现 IDisposable 并且需要在 using 块中使用。
我打算使用JsonElement. 这是最合适的选择还是有任何其他类型可用于将 JSON 作为对象保存?
回答
最接近的等价物JObject确实是JsonElement这样,您可以按如下方式修改您的 DTO:
public class MyDTO
{
public JsonElement ExtractedData {get;set;}
}
无需担心处理任何文档,因为在内部,JsonElementConverterused byJsonSerializer返回非池化元素(通过在 .NET 5 中克隆该元素)。
但是,对应关系并不准确,因此请记住以下几点:
-
JsonElement表示任何 JSON 值,因此最接近于JTokennotJObject。由于JsonElement是struct不存在对应于JSON对象没有子类。如果要限制ExtractedData为 JSON 对象,则需要在 setter 中进行检查:public class MyDTO { JsonElement extractedData; public JsonElement ExtractedData { get => extractedData; set { if (value.ValueKind != JsonValueKind.Object // && value.ValueKind != JsonValueKind.Null Uncomment if you want to allow null ) throw new ArgumentException(string.Format("{0} is not a JSON object type", value.ValueKind)); extractedData = value; } } } -
由于
JsonElement是结构,因此默认值不是null。那么,它是什么?事实证明,default(JsonElement)有ValueKind = JsonValueKind.Undefined:没有值(与 Null 不同)。
如果你试图序列这样的默认值
JsonElement与JsonSerializer一个异常将被抛出。也就是说,如果你只是这样做var json = JsonSerializer.Serialize(new MyDTO());然后
System.InvalidOperationException: Operation is not valid due to the current state of the object.抛出异常。您有几个选项可以避免此问题:
-
在 .NET 5 中,您可以这样申请
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]:public class MyDTO { [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public JsonElement ExtractedData {get;set;} }这会导致
ExtractedData在序列化期间跳过未初始化的值。 -
在 .NET Core 3.x
JsonIgnoreCondition中不存在,因此您可以改为定义ExtractedData为可空:public class MyDTO { public JsonElement? ExtractedData {get;set;} }或者您可以将其初始化为 null,
JsonElement如下所示:public class MyDTO { public JsonElement ExtractedData {get;set;} = JsonExtensions.Null; } public static class JsonExtensions { static readonly JsonElement nullElement = CreateNull(); public static JsonElement Null => nullElement; static JsonElement CreateNull() { using var doc = JsonDocument.Parse("null"); return doc.RootElement.Clone(); } }这两个选项都会导致 的未初始化值
ExtractedData序列化为null。
-
-
另请参阅相关问题:
- 将 newtonsoft 代码转换为 System.Text.Json in .net core 3. 相当于 JObject.Parse 和 JsonProperty。
- 由于对象 (System.Text.Json) 的当前状态,操作无效。