gpt4 book ai didi

c# - 在 JsonConverter.ReadJson() 中有效地获取完整的 json 字符串

转载 作者:行者123 更新时间:2023-12-04 12:42:25 24 4
gpt4 key购买 nike

如何在 JsonConverter.ReadJson() 中高效获取完整的 json 字符串?

我能做到:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
var json = JObject.Load(reader).ToString(Formatting.None);

然而,这似乎非常低效,因为我无缘无故地序列化和反序列化

有什么更好的方法吗?

最佳答案

ReadJson() 必须完全解析正在读取的 JSON,以便确认 JSON 格式正确并且 JsonReader 正确定位在当前值的末尾导出。但是,不必将整个 JSON 加载到中间 JObject 层次结构中,只需将其重新转换为 JSON 字符串即可。相反,您可以通过使用 JRaw.Create() 获得更好的性能:

var json = JRaw.Create(reader).ToString();

reference source 中可以看出,此方法直接从传入的 JsonReader 流式传输到 StringWriter - 无需加载到中间 JToken层次结构和重新序列化 - 通过使用 JsonWriter.WriteToken(JsonReader) :

public static JRaw Create(JsonReader reader)
{
using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.WriteToken(reader);

return new JRaw(sw.ToString());
}
}

生成的 JRaw 只是将该字符串封装在其 Value 中。 (当然,不能保证生成的 JSON 代表一个对象,只能保证它代表格式正确的 JSON。)

请注意,JsonTextReader 会自动将 common formats 中的日期和时间识别并解析为 DateTime 对象,并将浮点值解析为 double。如果您需要“最直接”的 JSON 字符串,您可能希望抑制 DateTime 识别和/或将浮点值解析为 decimal。以下扩展方法以 JRaw.Create() 为模型,可以完成这项工作:

public static string ReadOuterJson(this JsonReader reader, Formatting formatting = Formatting.None, DateParseHandling? dateParseHandling = null, FloatParseHandling? floatParseHandling = null)
{
// If you would prefer a null JSON value to return an empty string, remove this line:
if (reader.TokenType == JsonToken.Null)
return null;
var oldDateParseHandling = reader.DateParseHandling;
var oldFloatParseHandling = reader.FloatParseHandling;
try
{
if (dateParseHandling != null)
reader.DateParseHandling = dateParseHandling.Value;
if (floatParseHandling != null)
reader.FloatParseHandling = floatParseHandling.Value;
using (var sw = new StringWriter(CultureInfo.InvariantCulture))
using (var jsonWriter = new JsonTextWriter(sw) { Formatting = formatting })
{
jsonWriter.WriteToken(reader);
return sw.ToString();
}
}
finally
{
reader.DateParseHandling = oldDateParseHandling;
reader.FloatParseHandling = oldFloatParseHandling;
}
}

然后像这样调用它,例如:

var json = reader.ReadOuterJson(dateParseHandling: DateParseHandling.None);

有关为什么需要这样做的详细信息,请参阅:

关于c# - 在 JsonConverter.ReadJson() 中有效地获取完整的 json 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56944160/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com