Rene Sá
Rene Sá

Reputation: 4

How work with JSON correctly

My app for Windows Phone have a collection from a JSON (WebService of Google Calendar).

I can get the JSON correctly, but when does the Parse, get an error: Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObject. Path", line 1, position 1.

I not know if this is the problem, but never worked with a complex JSON. Example: the "tag" dateTime on JSON is "inside" of start and another inside of end. How, on my collection, I define this?

JSON response:

{
kind: "calendar#events",
etag: ""1416310700455000"",
summary: "[email protected]",
updated: "2014-11-18T11:38:20.455Z",
timeZone: "America/Sao_Paulo",
accessRole: "reader",
defaultReminders: [ ],
nextSyncToken: "CNjoxMGf",
    items: [
            {
              kind: "calendar#event",
              etag: ""283f00"",
              id: "sf00g1go9399gf",
              status: "confirmed",
              htmlLink: "https://www.google.com/calendar/event?eid=c2YwMGcxZ285Mzk5Z3YxcTU2Nml2dGl2b3MfiaWxlQGluZmFzc3RlYy5jb20uYnI",
              created: "2014-11-17T17:23:05.000Z",
              updated: "2014-11-17T17:23:05.362Z",
              summary: "Exemplo 1",
              creator: {
              email: "[email protected]",
              displayName: "Infass silva",
              self: true
              },
              organizer: {
              email: "[email protected]",
              displayName: "Infass silva",
              self: true
              },
              start: {
              dateTime: "2014-11-17T17:00:00-02:00"
              },
              end: {
              dateTime: "2014-11-17T18:00:00-02:00"
              },
              iCalUID: "[email protected]",
              sequence: 0
              }
]}

C#:

                DataContext = this;

                // String JSON
                string json1 = text;

                // Parse JObject
                JArray jObj1 = JArray.Parse(json1);

                Comp = new ObservableCollection<Compromisso>(
 jObj1.Children().Select(jo1 => jo1.ToObject<Compromisso>()));

            }
        }
    }

    public ObservableCollection<Compromisso> Comp { get; set; }

    public class Compromisso
    {
        public string summary { get; set; }
        public string dateTime { get; set; }
        public string location { get; set; }
        public string description { get; set; }
    }

Upvotes: 2

Views: 1212

Answers (1)

sibbl
sibbl

Reputation: 3229

The easiest way is to use the JSON to class pasting functionality of Visual Studio:

First of all, convert your JS object to a JSON string (e.g. with this tool). Copy the JSON output into clipboard and go into some class in Visual Studio. Use Edit > Paste Special > Paste JSON As Classes.

You should get the following output generated:

public class Rootobject
{
    public string kind { get; set; }
    public string etag { get; set; }
    public string summary { get; set; }
    public DateTime updated { get; set; }
    public string timeZone { get; set; }
    public string accessRole { get; set; }
    public object[] defaultReminders { get; set; }
    public string nextSyncToken { get; set; }
    public Item[] items { get; set; }
}

public class Item
{
    public string kind { get; set; }
    public string etag { get; set; }
    public string id { get; set; }
    public string status { get; set; }
    public string htmlLink { get; set; }
    public DateTime created { get; set; }
    public DateTime updated { get; set; }
    public string summary { get; set; }
    public Creator creator { get; set; }
    public Organizer organizer { get; set; }
    public Start start { get; set; }
    public End end { get; set; }
    public string iCalUID { get; set; }
    public int sequence { get; set; }
}

public class Creator
{
    public string email { get; set; }
    public string displayName { get; set; }
    public bool self { get; set; }
}

public class Organizer
{
    public string email { get; set; }
    public string displayName { get; set; }
    public bool self { get; set; }
}

public class Start
{
    public DateTime dateTime { get; set; }
}

public class End
{
    public DateTime dateTime { get; set; }
}

With the following code, you can deserialize it:

MemoryStream jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(text));
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Rootobject));
Rootobject rootObj = ser.ReadObject(jsonStream);

However, I am unsure whether this works 100% with your JS object because etag isn't surrounded by only a " but two "". I've never seen this.

However, it should answer your question on how to map JSON to classes.

Upvotes: 3

Related Questions