【问题标题】:Deserialize JSON Array with No Member Names to C# Object将没有成员名称的 JSON 数组反序列化为 C# 对象
【发布时间】:2018-07-07 17:23:21
【问题描述】:

我正在搜索一种将数组(没有成员名称) 反序列化为 C# 对象的方法。提供了工作和预期的示例,我看到了许多类似的帖子,但不是我想要的,因此为什么要寻求一些帮助。

我是否需要采用实现自定义反序列化的方法,还是我错过了一些已经存在的东西?

    // Deserialize Works This Way
    public class Order
    {
        public string orderNo { get; set; }
        public string customerNo { get; set; }
        public List<List<double>> items { get; set; }
    }

    // Expected Covert Type.
    public class OrderExpected
    {
        public string orderNo { get; set; }
        public string customerNo { get; set; }
        public List<OrderItem> items { get; set; }
    }

    public class OrderItem
    {
        public int itemId { get; set; }
        public decimal price { get; set; }
        public decimal quantity { get; set; }
    }

我尝试过的代码以及我想做什么:

     var json = "{\"orderNo\":\"AO1234\",\"customerNo\":\"C0129999\",\"items\":[[255, 1.65, 20951.60],[266, 1.80, 20000.00],[277, 1.90,0.50]]}";
     // Works OK, but ins't what I am after
     var order = JsonConvert.DeserializeObject<Order>(json);

     // I'd like to get some help to get this approch working.
     var orderexpected = JsonConvert.DeserializeObject<OrderExpected>(json);

关于 items 数组的更多信息: items 数组将由固定长度为 3 的数组组成,值分别代表 itemId、价格和数量。

附:我正在使用一个不受我控制的 API。

【问题讨论】:

标签: c# arrays json serialization json.net


【解决方案1】:

这可以帮助你..

public class OrderExpected
{
    public string orderNo { get; set; }
    public string customerNo { get; set; }
    public List<OrderItem> items { get; set; }
}

[JsonConverter(typeof(OrderItemConverter))]
public class OrderItem
{
    public int itemId { get; set; }
    public decimal price { get; set; }
    public decimal quantity { get; set; }
}

public class OrderItemConverter : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return objectType.Name.Equals("OrderItem");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {

        JArray array =  JArray.Load(reader);
        return new OrderItem { 
            itemId = array[0].ToObject<int>(),
            price = array[1].ToObject<decimal>(),
            quantity = array[2].ToObject<decimal>()
        }; 
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var orderItem = value as OrderItem;
        JArray arra = new JArray();
        arra.Add(orderItem.itemId);
        arra.Add(orderItem.price);
        arra.Add(orderItem.quantity);
        arra.WriteTo(writer);
    }
}

使用..

        string jsonString = "{\"orderNo\":\"AO1234\",\"customerNo\":\"C0129999\",\"items\":[[255, 1.65, 20951.60],[266, 1.80, 20000.00],[277, 1.90,0.50]]}";
        var objectResult = JsonConvert.DeserializeObject<OrderExpected>(jsonString);
        var serializationResult = JsonConvert.SerializeObject(objectResult);
        Console.WriteLine(serializationResult);
        // output : {"orderNo":"AO1234","customerNo":"C0129999","items":[[255,1.65,20951.6],[266,1.8,20000.0],[277,1.9,0.5]]}

【讨论】:

  • 流畅而完整的解决方案。谢谢!
【解决方案2】:

您可以通过使用属性为指定的属性使用自定义 JsonConverter:JsonConverter(typeof(YourCustomConverter))

在您的情况下,简单示例应如下所示:

public class OrderExpected
{
    public string OrderNo { get; set; }
    public string CustomerNo { get; set; }
    [JsonConverter(typeof(OrderItemConverter))]
    public List<OrderItem> Items { get; set; }
}

public class OrderItemConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;

        var jArray = JArray.Load(reader);
        var result = new List<OrderItem>();
        foreach (var arrayItem in jArray)
        {
            var innerJArray = arrayItem as JArray;
            if(innerJArray?.Count != 3)
                continue;

            result.Add(new OrderItem
            {
                ItemId = (int) innerJArray[0],
                Price = (decimal)innerJArray[1],
                Quantity = (decimal)innerJArray[2]
            });
        }

        return result;
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }
}

像往常一样反序列化你的 json。

var obj = JsonConvert.DeserializeObject<OrderExpected>(json);

【讨论】:

    【解决方案3】:

    好的,我同意 Levent。我只想开发这个答案! 在 Json.Net 端使用此属性 [JsonExtensionData] 当 Json 字符串包含没有属性名称的属性时

    [Serializable]
    [JsonObject]
    public class Price
    {
        [JsonExtensionData]
        public IDictionary<string, JToken> Values { get; set; }
        [JsonProperty("vendor")]
        public Dictionary<string, string> vendor { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-28
      • 2019-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多