C# 序列化有时是数组的Json属性

C# 序列化有时是数组的Json属性,c#,json.net,C#,Json.net,是否有任何方法可以在单个操作中序列化从decimal到decimal[]不等的Json对象属性 在我的Json产品提要中,特价商品表示为一个数组(正常价格/销售价格)。普通商品就是价格。像这样: [ { "product" : "umbrella", "price" : 10.50, }, "product" : "chainsaw", "price" : [ 39.99,

是否有任何方法可以在单个操作中序列化从decimal到decimal[]不等的Json对象属性

在我的Json产品提要中,特价商品表示为一个数组(正常价格/销售价格)。普通商品就是价格。像这样:

[
    {
        "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<Product>>(jsonArray);
公共类产品
{
公共字符串乘积{get;set;}
公共对象价格{get;set;}
}
var productList=JsonConvert.DeserializeObject(jsonArray);
但若我尝试将其设为十进制[],那个么它将对单个十进制值抛出异常。将其设置为对象意味着数组值是JArray,因此我必须在以后做一些清理工作,并且我的应用程序中的其他映射要求属性类型准确,因此我必须将其映射到未映射的属性,然后初始化另一个属性,这没什么大不了的,但命名有点混乱


object是这里唯一的选项,还是我可以用序列化程序为数组添加一个值,或者为特价向单独的属性添加第二个值?您必须为该
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<List<Product>>(jsonStr);
var productList=JsonConvert.DeserializeObject(jsonStr);

另一种方法是添加一个Json字段,该字段是
动态的
,并用
JsonProperty
属性对其进行标记,以便与实际的Json对齐。然后在.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<Foo>(json);
        var foo2 = JsonConvert.DeserializeObject<Foo>(json2);

        foo1.Price.ForEach(Console.WriteLine);
        foo2.Price.ForEach(Console.WriteLine);
    }
}

public class Foo {
    [JsonProperty(PropertyName = "price")]
    public dynamic priceJson { get; set; }

    private List<int> _price;

    public List<int> Price {
        get {
            if (_price == null) _price = new List<int>();

            _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;
        }
    }
}
使用系统;
使用System.Linq;
使用System.Collections.Generic;
使用Newtonsoft.Json;
使用Newtonsoft.Json.Linq;
公共课程
{
公共静态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);
}
}
公开课Foo{
[JsonProperty(PropertyName=“price”)]
公共动态价格JSON{get;set;}
私人清单价格;
公开标价{
得到{
如果(_price==null)_price=new List();
_price.Clear();
if(priceJson是Newtonsoft.Json.Linq.JArray){
foreach(priceJson中的var价格){
_价格。添加((整数)价格);
}
}否则{
_添加((int)priceJson);
}
退货价格;
}
}
}

现场示例位于:

而不是使用
对象
尝试
动态
公共动态价格{get;set;}
如果提交
MyConverter()
作为反序列化方法的参数,是否必须在类型上指定属性?谢谢!这很好用。我设置了一个“decimal[]RawPrice”,然后设置了“Price”和“SalePrice”,使用getter/setter访问它,所有事情都在一个操作中发生,我的类在其他地方映射得很好:)谢谢!。我结合使用了这种方法和自定义转换器