使用动态键从请求正文中反序列化 JSON

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

我有一个 Rest API,它接受由动态 GUID 字段组成的 JSON 模型。

我尝试了多种模型,但在所有模型中都出现错误。

这是 JSON:

{
   "meta_data": {
       "name": "myname"
   },
   "1122413f-2887-4789-a112-31d003f2703a": {
       "ipadd": "1.1.1.1",
       "host": "host"
   },
   "4432313f-2887-4789-a222-31d41231233a": {
       "ipadd": "1.2.1.1",
       "host": "h3st"
   }
}

这是模型:

public class RootObject
{
    [JsonProperty("meta_data")]
    public Metadata Metadata { get; set; }

    public Dictionary<Guid, DeviceInfo> Devices { get; set; }
}

public class DeviceInfo
{
    public string IpAdd { get; set; }
    public string Host { get; set; }
}

和控制器:

[FromBody] RootObject jsonObj

jsonObj
仅包含
Metadata
,动态字段始终为空。

我可以做什么来克服这个问题?

当我在

Devices
下发送时它会接受:

"Devices": { 
     "123...."
}

但这不是我需要的。

c# json rest .net-6.0 json-deserialization
1个回答
1
投票

如果您使用 .NET Core 3 及更高版本,则可以使用 System.Text.Json.Serialization

中的 
JsonExtensionDataAttribute

您应该添加一个新属性来接收附加 JSON 元素,如

Dictionary<string, JsonElement>

字典的TKey值必须是String,TValue必须是JsonElement或Object。

并通过一些数据转换将其分配给

Devices
属性。

using System.Text.Json.Serialization;
using System.Linq;

public class RootObject
{
    [JsonPropertyName("meta_data")]
    public Metadata Metadata { get; set; }

    [JsonExtensionData]
    public Dictionary<string, JsonElement> Extension { get; set; }
    
    [JsonIgnore]
    public Dictionary<Guid, DeviceInfo> Devices 
    { 
        get
        {
            if (Extension == null)
                return null;

            return Extension.ToDictionary(x => Guid.Parse(x.Key), v => JsonSerializer.Deserialize<DeviceInfo>(JsonSerializer.Serialize(v.Value)));
        }
    }
}

public class DeviceInfo
{
    [JsonPropertyName("ipadd")]
    public string IpAdd { get; set; }
    
    [JsonPropertyName("host")]
    public string Host { get; set; }
}


如果您使用 Newtonsoft.Json 作为 API/MVC 应用程序中的默认序列化库/工具:

services.AddControllers()
    .AddNewtonsoftJson();

您需要使用Newtonsoft.Json中的属性/反序列化方式。

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class RootObject
{
    [JsonProperty("meta_data")]
    public Metadata Metadata { get; set; }

    [JsonExtensionData]
    public Dictionary<string, JToken> Extension { get; set; }

    [JsonIgnore]
    public Dictionary<Guid, DeviceInfo> Devices
    {
        get
        {
            if (Extension == null)
                return null;

            return Extension.ToDictionary(x => Guid.Parse(x.Key), 
                v => JObject.FromObject(v.Value)
                    .ToObject<DeviceInfo>());
        }
    }
}

public class DeviceInfo
{
    [JsonProperty("ipadd")]
    public string IpAdd { get; set; }

    public string Host { get; set; }
}

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