web-dev-qa-db-ja.com

Jsonオブジェクトを逆シリアル化するときに、「型が正しく逆シリアル化するためにJSON配列([1,2,3]など)が必要なため」エラーが発生する

私を助けてください。どこに情報がありませんか?次のJSON文字列を逆シリアル化する必要があります。

{"results":[{"series":[{"name": "PWR_00000555"、 "columns":["time"、 "last"]、 "values":[["1970-01-01T00:00: 00Z "、72]]}]}]}

このために、クラスを定義しました。

public class Serie
{
    public Serie()
    {
        this.Points = new List<object[]>();
    }

    [JsonProperty(PropertyName = "results")]
    public string results { get; set; }

    [JsonProperty(PropertyName = "series")]
    public string sries { get; set; }


    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }

    [JsonProperty(PropertyName = "columns")]
    public string[] ColumnNames { get; set; }

    [JsonProperty(PropertyName = "values")]
    public List<object[]> Points { get; set; }

しかし、デシリアライザーを使おうとすると、例外が発生します。

{"現在のJSONオブジェクト(例:{\" name\":\" value\"})をタイプ 'System.Collections.Generic.List`1 [InfluxDB.Serie]'に逆シリアル化できません。これは、タイプにJSON配列が必要なためです(例:[1,2,3])を正しく逆シリアル化します。\ r\nこのエラーを修正するには、JSONをJSON配列(例:[1,2,3])に変更するか、逆シリアル化されたタイプを通常のように変更します。 JSONオブジェクトから逆シリアル化できるNETタイプ(たとえば、整数のようなプリミティブタイプではなく、配列やList <T>のようなコレクションタイプではありません)。JsonObjectAttributeをタイプに追加して、JSONオブジェクトから逆シリアル化することもできます。 。\ r\nPath'results '、line 2、position 12. "}

4
user649459

クラスが基本的にフラットであるのに対し、JSONは階層的であるため、このエラーが発生します。 JSONLint.com を使用してJSONを検証および再フォーマットすると、構造がよくわかります。

{
    "results": [
        {
            "series": [
                {
                    "name": "PWR_00000555",
                    "columns": [
                        "time",
                        "last"
                    ],
                    "values": [
                        [
                            "1970-01-01T00:00:00Z",
                            72
                        ]
                    ]
                }
            ]
        }
    ]
}

これは、次のクラス構造に対応します(最初に json2csharp.com を使用して生成し、次に手動で編集して[JsonProperty]属性を追加しました)。

public class RootObject
{
    [JsonProperty("results")]
    public List<Result> Results { get; set; }
}

public class Result
{
    [JsonProperty("series")]
    public List<Series> Series { get; set; }
}

public class Series
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("columns")]
    public List<string> ColumnNames { get; set; }
    [JsonProperty("values")]
    public List<List<object>> Points { get; set; }
}

JSONを次のように上記のクラス構造に逆シリアル化できます。

var root = JsonConvert.DeserializeObject<RootObject>(jsonString);

フィドル: https://dotnetfiddle.net/50Z64s

15
Brian Rogers

IntelliSenseを犠牲にして、時間型の安全性をコンパイルする場合は、JSONを動的オブジェクトに逆シリアル化するだけです。

dynamic parsed = JsonConvert.DeserializeObject(jsonString);
PrintAllNames(parsed);

//...

private void PrintAllNames(dynamic obj)
{
    foreach(var result in obj.results)
        foreach(var item in result.series)
            Console.WriteLine(item.name);
}
4
Matias Cicero