我如何反序列化 JSON 其中有一个 ane/value 属性数组以及具有三个值的位置?

How do I deserialize JSON where there is an array of ane/value properties along with a Location which has three values?

我正在尝试将 HTTP 请求反序列化为 C# POCO class。

JSON是:

    {
        "applicationId":"4284f0b0-61f9-4a9d-8894-766f7b9605b5",
        "deviceId":"testdevice22",
        "messageType":"cloudPropertyChange",
        "properties":[
                       {"name":"CustomerID","value":202},
                       {"name":"DeviceSerialNumber","value":"devicesa999"},
                       {"name":"Location","value":{
                                                    "alt":0,
                                                    "lat":41.29111465188208,
                                                    "lon":-80.91897192058899
                                                  }}
                    ],
    }

POCO 是:

public class CustomEventModel
{
     public string applicationId { get; set; }
     public string deviceId { get; set; }
     public List<PropertyAttribute> properties { get; set; }
}

public class PropertyAttribute
{
    public string name { get; set; }

    public string value { get; set; }
}

在我的函数应用程序中,我有:

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    var propertyChangeData = JsonConvert.DeserializeObject<CustomEventModel>(requestBody);

异常消息是:2022-05-27T23:14:42.141 [错误] CustomEventModel 错误:解析值时遇到意外字符:{。路径 'properties[7].value',第 1 行,

都与Location项有关。我该如何解决?

“位置”的值为

{
    "alt":0,
    "lat":41.29111465188208,
    "lon":-80.91897192058899
}

这是一个复杂的对象,而其他“值”则不是。他们甚至不是同一类型。一种解决方案是创建一个自定义反序列化器,如下所述:https://www.newtonsoft.com/json/help/html/CustomJsonConverterGeneric.htm

然后用自定义类型(例如CustomValue)编写one-way从各种值类型的转换

public class CustomValueConverter : JsonConverter<CustomValue>
{
    public override Version ReadJson(JsonReader reader, Type objectType, CustomValue existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            var value = reader.Value;
            return new CustomValue(value);
        }
}

你的 PropertyAttribute class 现在看起来像这样:

public class PropertyAttribute
{
    public PropertyAttribute() {}
    public PropertyAttribute(object value)
    {
        //handle the various types of input in the constructor
    }
    public string name { get; set; }

    public CustomValue value { get; set; }
}

现在您可以像这样使用自定义值转换器进行反序列化:

var thing = JsonConvert.DeserializeObject<CustomEventModel>(json, new CustomValueConverter());

只需将值 属性 的类型从字符串更改为对象并添加位置 class

public class PropertyAttribute
{
    public string name { get; set; }

    private object _value;

    public object value
    {
        get
        {

            if (_value as JObject !=null)
            return  ((JObject)_value).ToObject<Location>();
            return _value?.ToString();
        }

        set { _value = value; }
    }
}

public class Location
{
    public int alt { get; set; }
    public double lat { get; set; }
    public double lon { get; set; }
}

如何使用

var propertyChangeData = JsonConvert.DeserializeObject<CustomEventModel>(requestBody);
    
Location location = (Location) propertyChangeData.properties.Where(p => p.name=="Location").FirstOrDefault().value;

string DeviceSerialNumber = (string) propertyChangeData.properties.Where(p => p.name=="DeviceSerialNumber").FirstOrDefault().value;