序列化Json属性,有时候是一个数组

有没有办法在单个操作中序列化从十进制到十进制[]的Json对象属性?

在我的Json产品Feed中,特价商品表示为数组(正常价格/促销价)。 普通商品只是价格。 像这样:

[ { "product" : "umbrella", "price" : 10.50, }, "product" : "chainsaw", "price" : [ 39.99, 20.0 ] } ] 

我可以让它工作的唯一方法是,如果我将属性设置为这样的对象:

 public class Product { public string product { get; set; } public object price { get; set; } } var productList = JsonConvert.DeserializeObject<List>(jsonArray); 

但是,如果我尝试使其成为decimal [],那么它将在单个十进制值上抛出exception。 使它成为一个对象意味着数组值是一个JArray所以我以后必须做一些清理工作,我的应用程序中的其他映射要求属性类型是准确的所以我必须将其映射到未映射的属性然后初始化另一个属性没什么大不了的,但命名有点混乱。

对象是这里唯一的选择还是我可以使用序列化程序做一些魔法,要么将单个值添加到数组,要么将第二个值添加到单独的属性以获得特价?

您必须为该price属性编写自定义转换器(因为它的格式不正确),并使用如下所示:

  public class Product { public string product { get; set; } [JsonConverter(typeof(MyConverter ))] public decimal[] price { get; set; } } public class MyConverter : JsonConverter { public override bool CanConvert(Type objectType) { return false; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if(reader.TokenType == JsonToken.StartArray) { return serializer.Deserialize(reader, objectType); } return new decimal[] { decimal.Parse(reader.Value.ToString()) }; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } } 

然后正常解析:

  var productList = JsonConvert.DeserializeObject>(jsonStr); 

另一种方法是添加一个dynamic的Json字段,并用JsonProperty属性标记它,以便它与实际的Json JsonProperty 。 然后在.NET中使用真正的字段来获取Json字段并将其转换为真正的数组,如此…

 using System; using System.Linq; using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class Program { public static void Main() { var json = "{ \"price\": [ 10, 20 ] }"; var json2 = "{ \"price\": 15 }"; var foo1 = JsonConvert.DeserializeObject(json); var foo2 = JsonConvert.DeserializeObject(json2); foo1.Price.ForEach(Console.WriteLine); foo2.Price.ForEach(Console.WriteLine); } } public class Foo { [JsonProperty(PropertyName = "price")] public dynamic priceJson { get; set; } private List _price; public List Price { get { if (_price == null) _price = new List(); _price.Clear(); if (priceJson is Newtonsoft.Json.Linq.JArray) { foreach(var price in priceJson) { _price.Add((int)price); } } else { _price.Add((int)priceJson); } return _price; } } } 

现场样本: https : //dotnetfiddle.net/ayZBlL