JSON 反序列化自定义属性名称

问题描述 投票:0回答:1

我试图弄清楚如何将以下 JSON 文本反序列化为 C# 类,其中文件名是属性名称:

{
    "profile": {
        "content_settings": {
            "exceptions": {
                "sound": {
                    "file:///C:/Test.html": {
                        "last_modified": "13370213022229863",
                        "setting": 1
                    },
                    "file:///C:/Test2.html": {
                        "last_modified": "13375581306745971",
                        "setting": 1
                    }
                }
            }
        }
    }
}

我假设我必须编写一个自定义 JSON 转换器类,但我不确定如何去做,并且还没有找到其他有效的示例。

c# json json.net deserialization
1个回答
0
投票

要处理文件名(如 file:///C:/Test.html)显示为属性名称的 JSON 结构,您可以创建一个自定义转换器来将此 JSON 反序列化为 C# 类。 .NET 中的 JsonConverter 允许您手动解析每个属性并将其映射到模型中的字典。

具体操作方法如下:

  1. 定义您的类,使用 Dictionary 作为文件名映射。
  2. 实现自定义 JsonConverter 来动态反序列化文件名。

完整代码如下:

第 1 步:定义模型类

using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

public class Profile
{
    public ContentSettings ContentSettings { get; set; }
}

public class ContentSettings
{
    public Exceptions Exceptions { get; set; }
}

public class Exceptions
{
    public Dictionary<string, SoundSettings> Sound { get; set; }
}

public class SoundSettings
{
    public string LastModified { get; set; }
    public int Setting { get; set; }
}

第2步:实现自定义JsonConverter

要将文件名映射到字典,请使用如下自定义转换器:

public class ExceptionsConverter : JsonConverter<Exceptions>
{
    public override Exceptions Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var exceptions = new Exceptions { Sound = new Dictionary<string, SoundSettings>() };
        
        // Ensure we are at the start of the object
        if (reader.TokenType != JsonTokenType.StartObject)
            throw new JsonException();

        // Read until the end of the object
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject)
                break;

            // Get the filename as the property name
            string fileName = reader.GetString();
            reader.Read(); // Move to the value

            // Deserialize the value as SoundSettings
            var soundSetting = JsonSerializer.Deserialize<SoundSettings>(ref reader, options);
            exceptions.Sound[fileName] = soundSetting;
        }

        return exceptions;
    }

    public override void Write(Utf8JsonWriter writer, Exceptions value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();

        foreach (var item in value.Sound)
        {
            writer.WritePropertyName(item.Key);
            JsonSerializer.Serialize(writer, item.Value, options);
        }

        writer.WriteEndObject();
    }
}

第 3 步:应用转换器

使用 JsonConverter 修饰 Exceptions 类中的 Sound 属性以使用自定义转换器:

public class Exceptions
{
    [JsonConverter(typeof(ExceptionsConverter))]
    public Dictionary<string, SoundSettings> Sound { get; set; }
}

第4步:反序列化JSON

最后,反序列化JSON如下:

string json = // your JSON string here;
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
Profile profile = JsonSerializer.Deserialize<Profile>(json, options);

此设置应将每个文件名正确映射到字典中的 SoundSettings 对象。自定义转换器处理动态属性名称,允许您将它们作为 C# 中的字典键进行访问。

© www.soinside.com 2019 - 2024. All rights reserved.