在JsonConverter.ReadJson()中有效获取完整的json字符串 [英] Efficiently get full json string in JsonConverter.ReadJson()

查看:419
本文介绍了在JsonConverter.ReadJson()中有效获取完整的json字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I efficiently get full json string in JsonConverter.ReadJson() ?

我可以做到:

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

但是,由于我无缘无故地进行序列化和反序列化,这似乎效率很低

However that seems very inefficient as I serialize and deserialize for no reason

还有更好的方法吗?

推荐答案

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

ReadJson() must fully parse the JSON being read so that the JSON is confirmed to be well-formed and the JsonReader is correctly positioned at the end of the current value upon exit. However, it is not necessary to load the entire JSON into an intermediate JObject hierarchy simply to re-convert it to a JSON string. Instead, you may be able to get better performance by using JRaw.Create():

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

As can be seen in the reference source, this method streams directly from the incoming JsonReader to a StringWriter - without loading into an intermediate JToken hierarchy and re-serializing - by using 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.)

The resulting JRaw simply encapsulates that string in its Value. (Of course, there is no guarantee that the resulting JSON represents an object, only that it represents well-formed JSON.)

请注意,JsonTextReader将自动识别和解析常见格式为DateTime对象,并将浮点值解析为double.如果您需要最文字"的JSON字符串,则可能需要抑制DateTime识别和/或将浮点值解析为decimal.以JRaw.Create()为模型的以下扩展方法可以完成此任务:

Note that JsonTextReader will automatically recognize and parse dates and times in common formats as DateTime objects, and also parse floating point values as double. If you need the "most literal" JSON string you may want to suppress DateTime recognition and/or parse floating point values as decimal. The following extension method, modeled on JRaw.Create(), does the job:

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);

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

For details on why this may be necessary, see:

JObject.Parse修改浮点值的结尾 .

这篇关于在JsonConverter.ReadJson()中有效获取完整的json字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆