Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
239 views
in Technique[技术] by (71.8m points)

json - C# JSONConverter custom Serialization

I am receiving JSON from a certain API has a dynamic property.

I have taken a a custom JsonConverter approach. Is there a simpler way to deal with this?

Here is the JSON returned:

{
    "kind": "tm:ltm:pool:poolstats",
    "generation": 1,
    "selfLink": "https://localhost/mgmt/tm/ltm/pool/test-mypoolname_https_main/stats?ver=12.1.2",
    "entries": {
        "https://localhost/mgmt/tm/ltm/pool/test-mypoolname_https_main/~Common~test-mypoolname_https_main/stats": {
            "nestedStats": {
                "kind": "tm:ltm:pool:poolstats",
                "selfLink": "https://localhost/mgmt/tm/ltm/pool/test-mypoolname_https_main/~Common~test-mypoolname_https_main/stats?ver=12.1.2"
            }
        }
    }
}

The "entries": { "https://..." } is that part that always changes, depending on what I request from the API.

Here is the class structure that will hold this information:

public partial class PoolStatistics
{
    [JsonProperty("entries")]
    public EntriesWrapper Entries { get; set; }

    [JsonProperty("generation")]
    public long Generation { get; set; }

    [JsonProperty("kind")]
    public string Kind { get; set; }

    [JsonProperty("selfLink")]
    public string SelfLink { get; set; }


    [JsonConverter(typeof(PoolEntriesConverter))]
    public partial class EntriesWrapper
    {
        public string Name { get; set; }

        [JsonProperty("nestedStats")]
        public NestedStats NestedStats { get; set; }
    }

    public partial class NestedStats
    {
        [JsonProperty("kind")]
        public string Kind { get; set; }

        [JsonProperty("selfLink")]
        public string SelfLink { get; set; }
    }
}

Override to Deserialize, via the following on the PoolEntriesConverter:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    JObject jo = JObject.Load(reader);
    NestedStats nestedStats = (jo.First.First[NESTED_STATS]).ToObject<NestedStats>();

    EntriesWrapper entries = new EntriesWrapper
    {
        NestedStats = nestedStats,
        Name = jo.First.Path
    };

    return entries;
}

Overriden WriteJson (Serialization) - which is throwing an exception:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    EntriesWrapper entries = (EntriesWrapper)value;

    JObject jo = new JObject(
        new JProperty(NESTED_STATS, entries.NestedStats),
        new JProperty(entries.Name, entries.Name));
}

The error states:

System.ArgumentException: 'Could not determine JSON object type for type F5IntegrationLib.Models.Pools.PoolStatistics+NestedStats.'

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you declare a mode like

public class NestedStats
{
    public string kind { get; set; }
    public string selfLink { get; set; }
}

public class Entry
{
    public NestedStats NestedStats { get; set; }
}

public class Root
{
    public string kind { get; set; }
    public int generation { get; set; }
    public string selfLink { get; set; }
    public Dictionary<string, Entry> entries { get; set; }
}

Then you can deserialize as

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...