user1540911
user1540911

Reputation: 375

How will I get this json into my c# class

I would like to read in a json respons to my c# class for learning and having problem with it. This is the main code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using Newtonsoft.Json;


namespace ConsoleApplication2
{
class Program
{
    static void Main(string[] args)
    {

       var webClient = new System.Net.WebClient();
        var json = webClient.DownloadString("https://api.trafiklab.se/samtrafiken/resrobotstops/GetDepartures.json?key=[KEY]&apiVersion=2.2&locationId=7420752&coordSys=RT90");

This url will return this json

{"getdeparturesresult":{"departuresegment":[{"departure":{"location":
{"@id":"7420752","@x":"1271307","@y":"6404493","name":"Göteborg Brunnsparken"}
 ,"datetime":"2014-12-10 12:27"},"direction":"Göteborg Kålltorp","segmentid":
 {"mot":{"@displaytype":"S","@type":"SLT","#text":"Spårvagn"},"carrier":
 {"name":"Västtrafik","url":"http:\/\/www.vasttrafik.se\/","id":"279","number":"3"}}}, 

The first problem is that when generating a c# class it will complain about the @ in the variable name. How can this be fixed? I mean I cant change the json respons. That is what I get. My guess would be this:

getdeparturesresult.departuresegment.departure.location["@x"]);

The second is how will I write to get it in to my class? What should be used?

I have tried this but then it will complain about my RootObject:

string json = r.ReadToEnd();
List<RootObject> items = JsonConvert.DeserializeObject<List<RootObject>>(json);

Lets say I got a class like this

 public class Location
    {
        public string id { get; set; }
        public string x { get; set; }
        public string y { get; set; }
        public string name { get; set; }
    }

    public class Departure
    {
        public Location location { get; set; }
        public string datetime { get; set; }
    }

    public class Mot
    {
        public string displaytype { get; set; }
        public string type { get; set; }
        public string text { get; set; }
    }

    public class Carrier
    {
        public string name { get; set; }
        public string url { get; set; }
        public string id { get; set; }
        public string number { get; set; }
    }

    public class Segmentid
    {
        public Mot mot { get; set; }
        public Carrier carrier { get; set; }
    }

    public class Departuresegment
    {
        public Departure departure { get; set; }
        public string direction { get; set; }
        public Segmentid segmentid { get; set; }
    }

    public class Getdeparturesresult
    {
        public Departuresegment departuresegment { get; set; }
    }

    public class RootObject
    {
        public Getdeparturesresult getdeparturesresult { get; set; }
    }

I have also tried this

 dynamic array = JsonConvert.DeserializeObject(json);
  foreach (var item in array)
   {
        Console.WriteLine("{0}", item);
   }

This will printout whats in the json. But how do I get it to be read into my class? I cant figure it out. It must be simple but I cant get it right.

Upvotes: 1

Views: 162

Answers (2)

Dmitry Popov
Dmitry Popov

Reputation: 398

You could accomplish that with JavaScriptSerializer.

var root = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(json);

It worked for me, but I had to change the type of Getdeparturesresult.departuresegment property to an array:

public class Getdeparturesresult
{
    public Departuresegment[] departuresegment { get; set; }
}

Update:

To deserialize JSON properties with special characters with .NET, you can use DataContractJsonSerializer.

RootObject root;

using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
    root = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(RootObject)).ReadObject(stream) as RootObject;

But your code will have to get verbose. You need to mark every class with [DataContract] and every property with [DataMember] attributes. For the properties whose names are not equal to those of the source, use [DataMember(Name = "@fancy_name")].

[DataContract]
public class Location
{
    [DataMember(Name = "@id")]
    public string id { get; set; }
    [DataMember(Name = "@x")]
    public string x { get; set; }
    [DataMember(Name = "@y")]
    public string y { get; set; }
    [DataMember]
    public string name { get; set; }
}

// etc.

Upvotes: 1

Emil Lundin
Emil Lundin

Reputation: 597

You only need to change like:

public class Getdeparturesresult
{
   public IEnumerable<Departuresegment> departuresegment { get; set; }
}

You can still use the Json.net serializer (JsonConvert).

Edit: To handle the "@id" property you can do this:

[JsonProperty("@id")]
public string id { get; set; }

Upvotes: 3

Related Questions