System.Text.Json - 将嵌套对象反序列化为字符串 [英] System.Text.Json - Deserialize nested object as string

查看:83
本文介绍了System.Text.Json - 将嵌套对象反序列化为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 System.Text.Json.JsonSerializer 来部分反序列化模型,因此其中一个属性被读取为包含原始 JSON 的字符串.

I'm trying to use the System.Text.Json.JsonSerializer to deserialize the model partially, so one of the properties is read as string that contains the original JSON.

public class SomeModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Info { get; set; }
}

示例代码

var json = @"{
                 ""Id"": 1,
                 ""Name"": ""Some Name"",
                 ""Info"": {
                     ""Additional"": ""Fields"",
                     ""Are"": ""Inside""
                 }
             }";

var model = JsonSerializer.Deserialize<SomeModel>(json);

应该生成模型,其中 Info 属性包含来自原始 JSON 的 Info 对象作为字符串:

should produce the model, which Info property contains the Info object from the original JSON as string:

{
    "Additional": "Fields",
    "Are": "Inside"
}

它不能开箱即用并抛出异常:

It doesn't work out of the box and throws an exception:

System.Text.Json.JsonException: ---> System.InvalidOperationException:无法以字符串形式获取令牌类型StartObject"的值.

System.Text.Json.JsonException: ---> System.InvalidOperationException: Cannot get the value of a token type 'StartObject' as a string.

到目前为止我尝试了什么:

What have I tried so far:

public class InfoToStringConverter : JsonConverter<string>
{
    public override string Read(
        ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
    {
        return reader.GetString();
    }

    public override void Write(
        Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

并将其应用到模型中

[JsonConverter(typeof(InfoToStringConverter))]
public string Info { get; set; }

并将选项添加到 JsonSerializer

var options = new JsonSerializerOptions();
options.Converters.Add(new InfoToStringConverter());
var model = JsonSerializer.Deserialize<SomeModel>(json, options);

仍然抛出同样的异常:

System.Text.Json.JsonException: ---> System.InvalidOperationException:无法以字符串形式获取令牌类型StartObject"的值.

System.Text.Json.JsonException: ---> System.InvalidOperationException: Cannot get the value of a token type 'StartObject' as a string.

烹饪我需要的食物的正确食谱是什么?它使用 Newtonsoft.Json 以类似的方式工作.

What is the right recipe to cook what I need? It worked in a similar way using Newtonsoft.Json.

更新

对我来说,保持嵌套的 JSON 对象尽可能原始很重要.因此,我会避免使用反序列化为 Dictionary 并重新序列化之类的选项,因为我害怕引入不需要的更改.

For me it is important to keep the nested JSON object as original as possible. So, I'd avoid options like to deserialize as Dictionary and serialize back, because I'm afraid to introduce undesirable changes.

推荐答案

找到了如何正确读取 JsonConverter 中嵌套的 JSON 对象的正确方法.完整的解决方案如下:

Found a right way how to correctly read the nested JSON object inside the JsonConverter. The complete solution is the following:

public class SomeModel
{
    public int Id { get; set; }

    public string Name { get; set; }

    [JsonConverter(typeof(InfoToStringConverter))]
    public string Info { get; set; }
}

public class InfoToStringConverter : JsonConverter<string>
{
    public override string Read(
        ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using (var jsonDoc = JsonDocument.ParseValue(ref reader))
        {
            return jsonDoc.RootElement.GetRawText();
        }
    }

    public override void Write(
        Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

在代码本身中甚至不需要创建选项:

In the code itself there is no need even to create options:

var json = @"{
                 ""Id"": 1,
                 ""Name"": ""Some Name"",
                 ""Info"": {
                     ""Additional"": ""Fields"",
                     ""Are"": ""Inside""
                 }
             }";

var model = JsonSerializer.Deserialize<SomeModel>(json);

Info 属性中的原始 JSON 文本甚至包含示例中引入的额外空格,以提高可读性.

The raw JSON text in the Info property contains even extra spaces introduced in the example for nice readability.

并且没有混合模型表示及其序列化,正如@PavelAnikhouski 在他的回答中所说.

And there is no mixing of model representation and its serialization as remarked @PavelAnikhouski in his answer.

这篇关于System.Text.Json - 将嵌套对象反序列化为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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