【发布时间】:2021-06-08 09:17:10
【问题描述】:
我想将 JSON 流反序列化为 JToken 对象(可以是 JObject/JArray/JToken,但称为 JToken)。 我想将结果用作 JToken 对象,而不是像大多数示例所示的其他类实例。
如何做到这一点?
【问题讨论】:
标签: c# json serialization json.net
我想将 JSON 流反序列化为 JToken 对象(可以是 JObject/JArray/JToken,但称为 JToken)。 我想将结果用作 JToken 对象,而不是像大多数示例所示的其他类实例。
如何做到这一点?
【问题讨论】:
标签: c# json serialization json.net
要将Stream 加载为JToken,您可以使用以下任一方法:
JToken.Load(JsonReader, JsonLoadSettings)JsonSerializer.Deserialize<JToken>(JsonReader, JsonSerializerSettings)首先创建以下一种或两种方法:
public static partial class JsonExtensions
{
public static JToken LoadFromStream(Stream s, JsonLoadSettings settings = default, bool closeInput = true, FloatParseHandling? floatParseHandling = default, DateParseHandling? dateParseHandling = default)
{
using (var reader = new StreamReader(s))
using (var jsonReader = new JsonTextReader(reader) { CloseInput = closeInput })
{
if (floatParseHandling != null)
jsonReader.FloatParseHandling = floatParseHandling.Value;
if (dateParseHandling != null)
jsonReader.DateParseHandling = dateParseHandling.Value;
// You might also need to configure DateTimeZoneHandling, DateFormatString and Culture to fully control loading of dates and times.
return JToken.Load(jsonReader, settings);
}
}
public static T Deserialize<T>(Stream s, JsonSerializerSettings settings = default, bool closeInput = true)
{
// This method taken from this answer https://stackoverflow.com/a/22689976/3744182
// By https://stackoverflow.com/users/740230/ygaradon
// To https://stackoverflow.com/questions/8157636/can-json-net-serialize-deserialize-to-from-a-stream
// And modified to pass in settings and control whether the input stream is closed
using (var reader = new StreamReader(s))
using (var jsonReader = new JsonTextReader(reader) { CloseInput = closeInput })
{
JsonSerializer ser = JsonSerializer.CreateDefault(settings);
return ser.Deserialize<T>(jsonReader);
}
}
}
鉴于这些方法,您可以执行以下任一操作:
var token = JsonExtensions.LoadFromStream(stream, new JsonLoadSettings { /* Add your preferred load settings here */});
或者
var token = JsonExtensions.Deserialize<JToken>(stream, new JsonSerializerSettings { /* Add your preferred serializer settings here */ });
注意事项:
使用JsonLoadSettings 加载允许您控制是否加载行位置信息(存储为annotation 并且会占用大量内存)、是否加载cmets 以及如何处理duplicated property names。
可以通过直接在JsonTextReader 上设置必要的属性来控制浮点格式和日期/时间识别设置。
使用JsonSerializerSettings 反序列化允许控制多个解析选项,包括whether and how to recognize date/time strings as DateTime or DateTimeOffset 和whether to load floats as double or decimal。
使用JsonSerializer.Deserialize<JToken>()时不加载行位置信息。
演示小提琴here.
【讨论】: