将名称赋予数组数组

时间:2018-05-22 10:27:19

标签: c# arrays json json.net

我正在使用Newtonsoft将一些JSon解析为.Net类型。 json包含一个名为'data'的数组。我想让数据数组中的每个数组都是它自己的类型,但我不确定如何做到这一点。

希望下面的代码能够证明这一点。

    public class TheData
    {
        [JsonProperty(PropertyName = "data")]
        public List<object> dataItems { get; set; }
    }

用法:

        string json =
            "{\"data\":[[\"20180511\",1094391],[\"20180504\",1097315],[\"20180427\",1100221],[\"20180420\",1094455],[\"20180413\",1093023]]}";

        var myObj = JsonConvert.DeserializeObject<TheData>(json);

这没关系,但是,我想将dataItems的类型从List更改为List,如下所示:

    public class TheData
    {
        [JsonProperty(PropertyName = "data")]
        public List<DataItem> dataItems { get; set; }
    }

public class DataItem
{
    public string deldate { get; set; }
    public int value { get; set; }
}

然而,这会导致异常:

Newtonsoft.Json.JsonSerializationException occurred
  HResult=-2146233088
  Message=Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'CE.FOTools.Feeds2.EIA.DataItem' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'data[0]', line 1, position 10.

错误消息表明我想要的结果可能无法实现,但有人可以建议如何纠正这个问题吗?我无法控制JSON格式(一旦检索到,我就会对字符串进行操作)。如果这有任何不同,我正在使用.Net 4.5。

1 个答案:

答案 0 :(得分:2)

我认为最不突兀的方式是使用自定义转换器。例如:

class DataItemConverter : JsonConverter<DataItem> {
    public override void WriteJson(JsonWriter writer, DataItem value, JsonSerializer serializer) {
        // if item can be null - handle that
        writer.WriteStartArray();
        writer.WriteValue(value.deldate);
        writer.WriteValue(value.value);
        writer.WriteEndArray();
    }

    public override DataItem ReadJson(JsonReader reader, Type objectType, DataItem existingValue, bool hasExistingValue, JsonSerializer serializer) {
        var ar = serializer.Deserialize<List<object>>(reader);
        // perform some checks for length and data types, omitted here
        var result = new DataItem();
        result.deldate = (string) ar[0];
        result.value = Convert.ToInt32(ar[1]);
        return result;
    }
}

然后指定通过装饰您的类型来使用此转换:

[JsonConverter(typeof(DataItemConverter))]
public class DataItem {
    public string deldate { get; set; }
    public int value { get; set; }
}

之后它应该按照你的预期工作。

如果您的Json.NET版本中没有通用JsonConverter<> - 请使用非通用版本:

class DataItemConverter : JsonConverter {
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        var item = (DataItem) value;
        // if null is possible - handle that
        writer.WriteStartArray();
        if (item != null) {
            writer.WriteValue(item.deldate);
            writer.WriteValue(item.value);
        }

        writer.WriteEndArray();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        var ar = serializer.Deserialize<List<object>>(reader);
        // perform some checks for length and data types, omitted here
        var result = new DataItem();
        result.deldate = (string) ar[0];
        result.value = Convert.ToInt32(ar[1]);
        return result;
    }

    public override bool CanConvert(Type objectType) {
        return objectType == typeof(DataItem);
    }
}