简体   繁体   中英

Saving JSON data into a C# custom object

I've been playing with this for the past few days and I'm hoping someone could shed some light on what the issue could be.

I have this custom object that I created:

public class WorldInformation
{
    public string ID { get; set; }
    public string name { get; set; }
}

and this JSON data:

string world = "[{\"id\":\"1016\",\"name\":\"Sea of Sorrows\"}, {\"id\":\"1008\",\"name\":\"Jade Quarry\"},{\"id\":\"1017\",\"name\":\"Tarnished Coast\"},{\"id\":\"1006\",\"name\":\"Sorrow's Furnace\"},{\"id\":\"2014\",\"name\":\"Gunnar's Hold\"}]";

and I can sucessfully save the data in my custom object by deserializing it:

List<WorldInformation> worlds = JsonConvert.DeserializeObject<List<WorldInformation>>(world);

But...

When I create a custom object like this

public class EventItems
{
    public string World_ID { get; set; }
    public string Map_ID { get; set; }
    public string Event_ID { get; set; }
    public string State { get; set; }        
}

and have JSON data like this:

string eventItem = "{\"events\":[{\"world_id\":1011,\"map_id\":50,\"event_id\":\"BAD81BA0-60CF-4F3B-A341-57C426085D48\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":50,\"event_id\":\"330BE72A-5254-4036-ACB6-7AEED05A521C\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"0AC71429-406B-4B16-9F2F-9342097A50AD\",\"state\":\"Preparation\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"C20D9004-DF6A-4217-BF25-7D6B5788A94C\",\"state\":\"Success\"}]}";

I get an error when I try to deserialize it

 List<EventItems> events = JsonConvert.DeserializeObject<List<EventItems>>(eventItem);

The error message I get is:

Cannot deserialize the current JSON object (eg {"name":"value"}) into type 'System.Collections.Generic.List`1[WebApplication1.EventItems]' because the type requires a JSON array (eg [1,2,3]) to deserialize correctly.

To fix this error either change the JSON to a JSON array (eg [1,2,3]) or change the deserialized type so that it is a normal .NET type (eg not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

Path 'events', line 1, position 10.

In first case your json is array of objects, so deserialization into a list of your class type succeeds. In second case, your json is an object, and its "events" property is set to an array of objects, so it cannot be deserialized into a list.

What you may do, is change your class declaration:

public class EventItem
{
    public string World_ID { get; set; }
    public string Map_ID { get; set; }
    public string Event_ID { get; set; }
    public string State { get; set; }        
}

public class EventItems
{
    public EventItem[] Events { get; set; }
}

And deserialize it:

EventItems events = JsonConvert.DeserializeObject<EventItems>(eventItem);

Unforturnately there isn't a way to specify the root Json element like the XmlSerializer .

See How to deserialize JSON array with "root" element for each object in array using Json.NET?

public class EventItems
{
    public EventItems()
    {
        Events = new List<EventItem>();
    }

    public List<EventItem> Events { get; set; }
}

public class EventItem
{
    public string World_ID { get; set; }
    public string Map_ID { get; set; }
    public string Event_ID { get; set; }
    public string State { get; set; }        
}

Usage:

string eventItem = "{\"events\":[{\"world_id\":1011,\"map_id\":50,\"event_id\":\"BAD81BA0-60CF-4F3B-A341-57C426085D48\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":50,\"event_id\":\"330BE72A-5254-4036-ACB6-7AEED05A521C\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"0AC71429-406B-4B16-9F2F-9342097A50AD\",\"state\":\"Preparation\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"C20D9004-DF6A-4217-BF25-7D6B5788A94C\",\"state\":\"Success\"}]}";

var items = JsonConvert.DeserializeObject<EventItems>(eventItem);

Simply remove the object events from the 2nd JSON string:

string eventItem = "[{\"world_id\":1011,\"map_id\":50,\"event_id\":\"BAD81BA0-60CF-4F3B-A341-57C426085D48\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":50,\"event_id\":\"330BE72A-5254-4036-ACB6-7AEED05A521C\",\"state\":\"Active\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"0AC71429-406B-4B16-9F2F-9342097A50AD\",\"state\":\"Preparation\"},{\"world_id\":1011,\"map_id\":21,\"event_id\":\"C20D9004-DF6A-4217-BF25-7D6B5788A94C\",\"state\":\"Success\"}]";

It seems that your JSON string is not the same in both examples. On the first example, you're using a simple JSON array:

[
    {
        "id": "1016",
        "name": "Sea of Sorrows"
    },
    {
        "id": "1008",
        "name": "Jade Quarry"
    },
    {
        "id": "1017",
        "name": "Tarnished Coast"
    },
    {
        "id": "1006",
        "name": "Sorrow's Furnace"
    },
    {
        "id": "2014",
        "name": "Gunnar's Hold"
    }
]

And on the second example, you're assigning your array to an object ( events ):

{
    "events": 
    [
        {
            "world_id": 1011,
            "map_id": 50,
            "event_id": "BAD81BA0-60CF-4F3B-A341-57C426085D48",
            "state": "Active"
        },
        {
            "world_id": 1011,
            "map_id": 50,
            "event_id": "330BE72A-5254-4036-ACB6-7AEED05A521C",
            "state": "Active"
        },
        {
            "world_id": 1011,
            "map_id": 21,
            "event_id": "0AC71429-406B-4B16-9F2F-9342097A50AD",
            "state": "Preparation"
        },
        {
            "world_id": 1011,
            "map_id": 21,
            "event_id": "C20D9004-DF6A-4217-BF25-7D6B5788A94C",
            "state": "Success"
        }
    ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM