Reputation: 375
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
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
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