Using Json.net to deserialize Json with some changing object names - c#

I'm new here so thanks for the great content; invaluable stuff.
I'm deserializing some Json from TDAmeritrade into a C# desktop app using the "Option Chain" api.
Depending on the input to the api, I can get a response with multiple expiration dates, multiple strike prices, and multiple option objects.
Here's a link to a typical response: API ResponseTDAmeritrade Json Example
A snippet of the problem code:
"numberOfContracts": 8,
"putExpDateMap": {
**"2020-08-21:50": {
"15.0":** [
{
"putCall": "PUT",
"symbol": "FMCI_082120P15",
"description": "FMCI Aug 21 2020 15 Put",
"exchangeName": "OPR",
The problem is that the dates and strike prices change in each response. I've learned that I can deserialize into a "Dictionary<string, List<Type> listName" so I did that in the OptionChain and ExpDate classes but still can't get it working.
Here is the current error: error trace
Here are my classes, created from json2csharp.com but with the date and strike price classes modified:
class OptionChain
{
public string symbol { get; set; }
public string status { get; set; }
public Underlying underlying { get; set; }
public string strategy { get; set; }
public double interval { get; set; }
public bool isDelayed { get; set; }
public bool isIndex { get; set; }
public double interestRate { get; set; }
public double underlyingPrice { get; set; }
public double volatility { get; set; }
public double daysToExpiration { get; set; }
public int numberOfContracts { get; set; }
public Dictionary<string, List<expDate>> putExpDateMap { get; set; }
public Dictionary<string, List<expDate>> callExpDateMap { get; set; }
public class expDate
{
public Dictionary<string, List<StrikePrice>> strikePrices { get; set; }
}
public class StrikePrice
{
public Option[] options { get; set; }
}
public class Option
{
public string putCall { get; set; }
public string symbol { get; set; }
public string description { get; set; }
public string exchangeName { get; set; }
public double bid { get; set; }
public double ask { get; set; }
public double last { get; set; }
public double mark { get; set; }
public int bidSize { get; set; }
public int askSize { get; set; }
public string bidAskSize { get; set; }
public int lastSize { get; set; }
public double highPrice { get; set; }
public double lowPrice { get; set; }
public double openPrice { get; set; }
public double closePrice { get; set; }
public int totalVolume { get; set; }
public object tradeDate { get; set; }
public long tradeTimeInLong { get; set; }
public long quoteTimeInLong { get; set; }
public double netChange { get; set; }
public double volatility { get; set; }
public double delta { get; set; }
public double gamma { get; set; }
public double theta { get; set; }
public double vega { get; set; }
public double rho { get; set; }
public int openInterest { get; set; }
public double timeValue { get; set; }
public double theoreticalOptionValue { get; set; }
public double theoreticalVolatility { get; set; }
public OptionDeliverablesList optionDeliverablesList { get; set; }
public double strikePrice { get; set; }
public long expirationDate { get; set; }
public int daysToExpiration { get; set; }
public string expirationType { get; set; }
public long lastTradingDay { get; set; }
public double multiplier { get; set; }
public string settlementType { get; set; }
public string deliverableNote { get; set; }
public bool isIndexOption { get; set; }
public double percentChange { get; set; }
public double markChange { get; set; }
public double markPercentChange { get; set; }
public bool inTheMoney { get; set; }
public bool mini { get; set; }
public bool nonStandard { get; set; }
public class OptionDeliverablesList
{
public string symbol { get; set; }
public string assetType { get; set; }
public double deliverableUnits { get; set; }
public string currencyType { get; set; }
}
Am I doing something wrong in the Dictionaries? The way I understand it from my many hours of reading, the expiration dates and strike prices need to be read anonymously.
Thanks a bunch!

If I get your problem right - you have probelms deserializing json structure where keys are dynamic values but not static property names, correct? If so- you have modeled incorrect POCO (there are two nested dictionaries).
POCOs below give correct deserialization results (rest of properties skipped)
class OptionChain
{
public string Symbol { get; set; }
public string Status { get; set; }
public Dictionary<string, Dictionary<string, ExpDate[]>> PutExpDateMap { get; set; }
public Dictionary<string, Dictionary<string, ExpDate[]>> CallExpDateMap { get; set; }
//other properties ignored because dont matter
}
class ExpDate
{
public string ExchangeName { get; set; }
public decimal Bid { get; set; }
public decimal Ask { get; set; }
//other properties ignored because dont matter
}
Tested POCOs with json sample provided in your post:
static void Main(string[] args)
{
var t = File.ReadAllText("test.json");
var r = JsonConvert.DeserializeObject<OptionChain>(t);
Console.WriteLine($"Total elements in {nameof(r.PutExpDateMap)} : {r.PutExpDateMap.Count()}");
Console.WriteLine($"Keys in {nameof(r.PutExpDateMap)} : {string.Join(",", r.PutExpDateMap.Keys)}");
Console.WriteLine($"Total elements in {nameof(r.CallExpDateMap)} : {r.CallExpDateMap.Count()}");
Console.WriteLine($"Keys in {nameof(r.CallExpDateMap)} : {string.Join(",", r.CallExpDateMap.Keys)}");
}
Application output is:

Related

i can't deserialize changeable attribute date on my json api

I am use api use variable date whene date change the object name change like this if i have to get data of this day i use this :https://api.covid19tracking.narrativa.com/api/2020-11-05/country/us
and the result of json object is like this :
and if i have to choose other date i change the date and the variable of date object is change like this if i have to get data of 2020-10-11 ,i calll this:
https://api.covid19tracking.narrativa.com/api/2020-11-05/country/us , and this is image show the result and the change of object date
the problem is if i deserialize the api i get result from , metadata object ,total object , updated_at , and dates object and the other object date and countries give me this error
:NullReferenceException: Object reference not set to an instance of an object
I use https://json2csharp.com/ to get class from json and this is my code :
var client = new RestClient("https://api.covid19tracking.narrativa.com/api/2020-11-05/country/us");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
// request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
Root response = client.Execute<Root>(request)?.Data;
var paystoday_confirmed = response?.dates.date.countries.US.today_confirmed;
if (paystoday_confirmed != null)
{
Debug.Log("Confirmed :" + paystoday_confirmed);
}
and this is my object's
public class Link
{
public string href { get; set; }
public string rel { get; set; }
public string type { get; set; }
}
public class Link2
{
public string href { get; set; }
public string rel { get; set; }
public string type { get; set; }
}
public class SubRegion
{
public string date { get; set; }
public string id { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public string source { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_recovered { get; set; }
public int today_recovered { get; set; }
public double? today_vs_yesterday_confirmed { get; set; }
public double? today_vs_yesterday_deaths { get; set; }
public object today_vs_yesterday_recovered { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_recovered { get; set; }
}
public class Region
{
public string date { get; set; }
public string id { get; set; }
public List<Link2> links { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public string source { get; set; }
public List<SubRegion> sub_regions { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_open_cases { get; set; }
public int today_new_recovered { get; set; }
public int today_new_tests { get; set; }
public int today_new_total_hospitalised_patients { get; set; }
public int today_open_cases { get; set; }
public int today_recovered { get; set; }
public int today_tests { get; set; }
public int today_total_hospitalised_patients { get; set; }
public double? today_vs_yesterday_confirmed { get; set; }
public double? today_vs_yesterday_deaths { get; set; }
public double today_vs_yesterday_open_cases { get; set; }
public double? today_vs_yesterday_recovered { get; set; }
public double today_vs_yesterday_tests { get; set; }
public double? today_vs_yesterday_total_hospitalised_patients { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_open_cases { get; set; }
public int yesterday_recovered { get; set; }
public int yesterday_tests { get; set; }
public int yesterday_total_hospitalised_patients { get; set; }
}
public class US
{
public string date { get; set; }
public string id { get; set; }
public List<Link> links { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public List<Region> regions { get; set; }
public string source { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_open_cases { get; set; }
public int today_new_recovered { get; set; }
public int today_open_cases { get; set; }
public int today_recovered { get; set; }
public double today_vs_yesterday_confirmed { get; set; }
public double today_vs_yesterday_deaths { get; set; }
public double today_vs_yesterday_open_cases { get; set; }
public double today_vs_yesterday_recovered { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_open_cases { get; set; }
public int yesterday_recovered { get; set; }
}
public class Countries
{
public US US { get; set; }
}
public class Info
{
public string date { get; set; }
public string date_generation { get; set; }
public string yesterday { get; set; }
}
public class _20201102
{
public Countries countries { get; set; }
public Info info { get; set; }
}
public class Dates
{
[JsonProperty("2020-11-02")]
public _20201102 date { get; set; }
}
public class Metadata
{
public string by { get; set; }
public List<string> url { get; set; }
}
public class Total
{
public string date { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public string rid { get; set; }
public string source { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_open_cases { get; set; }
public int today_new_recovered { get; set; }
public int today_open_cases { get; set; }
public int today_recovered { get; set; }
public double today_vs_yesterday_confirmed { get; set; }
public double today_vs_yesterday_deaths { get; set; }
public double today_vs_yesterday_open_cases { get; set; }
public double today_vs_yesterday_recovered { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_open_cases { get; set; }
public int yesterday_recovered { get; set; }
}
public class Root
{
public Dates dates { get; set; }
public Metadata metadata { get; set; }
public Total total { get; set; }
public string updated_at { get; set; }
}
And this is the error on unity
It will work best if you use dictionaries.
You can make your dates and countries property a dictionary.
dates - Dates needs to be a dictionary because you can get data for different dates so the date will change
countries - The service u are using support other countries. If you change the countries to a dictionary, then the structure below should work for any country, not just for US.
Your code structure will then look something like this:
public class Root
{
public Dictionary<string, Date> dates {get;set;}
public Metadata metadata { get; set; }
public Total total { get; set; }
public string updated_at { get; set; }
}
public class Date
{
public Dictionary<string, Country> countries {get;set;}
public Info info {get;set;}
}
public class Country
{
....
//Country properties here
}
public class Info
{
....
//Info properties here
}
public class Metadata
{
....
//Metadata properties here
}
public class Total
{
....
//Total properties here
}
you should then be able to process the data as follow
foreach(var kvp in root.dates)
{
// the key will be the date eg. '2020-11-05'.
// This you can convert to a date using DateTime.Parse() if you need too.
Console.WriteLine(kvp.Key);
// The value will be the Date object
var dateObj = kvp.Value;
var info = dateObj.info;
foreach(var kvp2 in dateObj.countries)
{
Console.WriteLine(kvp2.Key); // this will be the country eg. 'US'
var countryDetails = kvp2.Value // this will be the Country object
}
}
Or just change your code too:
(note: you will need to know exactly what date was returned)
var paystoday_confirmed = response?.dates["2020-11-05"].countries["US"].today_confirmed;
if (paystoday_confirmed != null)
{
Debug.Log("Confirmed :" + paystoday_confirmed);
}
As already stated in the Comments your main issue here is that you hardcoded
public class Dates
{
[JsonProperty("2020-11-02")]
public _20201102 date { get; set; }
}
But as you can see in your second result the date simply is not 2020-11-02 but rather 2020-10-11!
Therefore in this case there is no object in the json representing the data object => It will be the default reference value null.
So how to solve this?
You could instead use a Dictionary .. however it depends a lot on how your JSON library works. I know that at least with JSON .Net the following should work
public class Root
{
public Dictionary<string, Date> dates { get; set; }
public Metadata metadata { get; set; }
public Total total { get; set; }
public string updated_at { get; set; }
}
public class Date
{
public Dictionary<string, Country> countries { get; set; }
public Info info { get; set; }
}
public class Country
{
public string date { get; set; }
public string id { get; set; }
public List<Link> links { get; set; }
public string name { get; set; }
public string name_es { get; set; }
public string name_it { get; set; }
public List<Region> regions { get; set; }
public string source { get; set; }
public int today_confirmed { get; set; }
public int today_deaths { get; set; }
public int today_new_confirmed { get; set; }
public int today_new_deaths { get; set; }
public int today_new_open_cases { get; set; }
public int today_new_recovered { get; set; }
public int today_open_cases { get; set; }
public int today_recovered { get; set; }
public double today_vs_yesterday_confirmed { get; set; }
public double today_vs_yesterday_deaths { get; set; }
public double today_vs_yesterday_open_cases { get; set; }
public double today_vs_yesterday_recovered { get; set; }
public int yesterday_confirmed { get; set; }
public int yesterday_deaths { get; set; }
public int yesterday_open_cases { get; set; }
public int yesterday_recovered { get; set; }
}
This also sounds more logic since dates indicates that there might be more then one item. And also countries sounds like there might not only be US but also other countries, maybe even multiple entries.
You would then access that e.g. like
foreach(var date in response.dates)
{
foreach(var country in date.value)
{
var paystoday_confirmed = country.value.today_confirmed;
Debug.Log($"Confirmed {paystoday_confirmed} cases for the {date.key} in {country.key}");
}
}
As complete alternative in the case you only need one certain field of your request anyway you could also use SimpleJson (simply copy the provided scripts somewhere into your project) and access them like
var root = JSON.Parse(theJsonString);
var paystoday_confirmed = root["Dates"]["2020-11-05"]["countries"]["US"]["today_confirmed"].AsInt();
For both solutions you will have to get rid of that RestClient package and rather do the UnityWebRequest.Get yourself and use the returned string instead.

FormatException during Json.net deserialization

I'm faced wiht an error, and I don't know how to correct it. I don't understand why it comes.
System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
The exception comes when I try to deserialize a JSON into objects that I created. (The second line code is throwing the exception)
List<Connection> connections = new List<Connection>();
var root = JsonConvert.DeserializeObject<RootObject2>(content);
connections = root.connections;
Here is the JSON that I want to use:
http://transport.opendata.ch/v1/connections?from=lausanne&to=fribourg
And here are my objects:
public class RootObject2
{
public List<Connection> connections { get; set; }
}
public class Connection
{
public Stop from { get; set; }
public Stop to { get; set; }
public string duration { get; set; }
public int? transfers { get; set; }
public Service service { get; set; }
public List<string> products { get; set; }
public int? capacity1st { get; set; }
public int? capacity2nd { get; set; }
public List<Section> sections { get; set; }
}
public class Stop
{
public Station station { get; set; }
public DateTime arrival { get; set; }
public int? arrivalTimestamp { get; set; }
public string departure { get; set; }
public int? departureTimestamp { get; set; }
public int? delay { get; set; }
public string platform { get; set; }
public Prognosis prognosis { get; set; }
public string realtimeAvailability {get; set;}
public Station location { get; set; }
}
public class Station
{
public string id { get; set; }
public string name { get; set; }
public int? score { get; set; }
public Coordinate coordinate { get; set; }
public double? distance { get; set; }
}
public class Service
{
public string regular { get; set; }
public string irregular { get; set; }
}
public class Section
{
public Journey journey { get; set; }
public Walk walk { get; set; }
public Stop departure { get; set; }
public Stop arrival { get; set; }
}
public class Journey
{
public string name { get; set; }
public string category { get; set; }
public string subcategory { get; set; }
public int? categoryCode { get; set; }
public string number { get; set; }
public string #operator { get; set; }
public string to { get; set; }
public List<Stop> passList { get; set; }
public int? capacity1st { get; set; }
public int? capacity2nd { get; set; }
}
public class Walk
{
public string duration { get; set; }
}
public class Prognosis
{
public string platform { get; set; }
public string arrival { get; set; }
public string departure { get; set; }
public int? capacity1st { get; set; }
public int? capacity2nd { get; set; }
}
public class Coordinate
{
public string type { get; set; }
public double x { get; set; }
public double y { get; set; }
}
The deserialization is on a try and catch block, and nothing is catched.
Also I am doing this on Android.
Based on json data.
Arrival property in Stop class should be DateTime?.

How to grab second occurring name from xml api data with C#

I'm trying to grab the high and low from this api, I am able to get the High, but can't figure out what to do to get the Low, which is the second occurring item with the name "fahrenheit", how could I do this using the same method I used for getting the High?
if (xmlForecast.Name == "fahrenheit" && i == 0)
{
i++;
xmlHigh = xmlForecast.ReadString();
}
Since you want solution using XML response, here it is:
First, you'll need to create classes which will represent XML response.
[XmlRoot("response")]
public class Response
{
[XmlElement("version")]
public string Version { get; set; }
[XmlElement("termsofService")]
public string TermsOfService { get; set; }
[XmlElement("features")]
public Features Features { get; set; }
[XmlElement("forecast")]
public Forecast Forecast { get; set; }
}
public class Features
{
[XmlElement("forecast")]
public int Forecast { get; set; }
}
public class Forecast
{
[XmlElement("txt_forecast")]
public TxtForecast TxtForecast { get; set; }
[XmlElement("simpleforecast")]
public SimpleForecast SimpleForecast { get; set; }
}
public class TxtForecast
{
[XmlElement("date")]
public string Date { get; set; }
[XmlArray("forecastdays")]
[XmlArrayItem("forecastday")]
public List<ForecastDay> ForecastDays { get; set; }
}
public class ForecastDay
{
[XmlElement("period")]
public int Period { get; set; }
[XmlElement("icon")]
public string Icon { get; set; }
[XmlElement("icon_url")]
public string IconUrl { get; set; }
[XmlElement("title")]
public string Title { get; set; }
[XmlElement("fcttext")]
public string FctText { get; set; }
[XmlElement("fcttext_metric")]
public string FctTextMetric { get; set; }
[XmlElement("pop")]
public string Pop { get; set; }
}
public class SimpleForecast
{
[XmlArray("forecastdays")]
[XmlArrayItem("forecastday")]
public List<ForecastDay2> ForecastDays { get; set; }
}
public class ForecastDay2
{
[XmlElement("date")]
public Date Date { get; set; }
[XmlElement("period")]
public int Period { get; set; }
[XmlElement("high")]
public High High { get; set; }
[XmlElement("low")]
public Low Low { get; set; }
[XmlElement("conditions")]
public string Conditions { get; set; }
[XmlElement("icon")]
public string Icon { get; set; }
[XmlElement("icon_url")]
public string IconUrl { get; set; }
[XmlElement("skyicon")]
public string SkyIcon { get; set; }
[XmlElement("pop")]
public int Pop { get; set; }
[XmlElement("qpf_allday")]
public QpfAllday QpfAllDay { get; set; }
[XmlElement("qpf_day")]
public QpfDay QpfDay { get; set; }
[XmlElement("qpf_night")]
public QpfNight QpfNight { get; set; }
[XmlElement("snow_allday")]
public SnowAllday SnowAllday { get; set; }
[XmlElement("snow_day")]
public SnowDay SnowDay { get; set; }
[XmlElement("snow_night")]
public SnowNight SnowNight { get; set; }
[XmlElement("maxwind")]
public MaxWind MaxWind { get; set; }
[XmlElement("avewind")]
public AveWind AveWind { get; set; }
[XmlElement("avehumidity")]
public int AveHumidity { get; set; }
[XmlElement("maxhumidity")]
public int MaxHumidity { get; set; }
[XmlElement("minhumidity")]
public int MinHumidity { get; set; }
}
public class Date
{
[XmlElement("epoch")]
public string Epoch { get; set; }
[XmlElement("pretty")]
public string Pretty { get; set; }
[XmlElement("day")]
public int Day { get; set; }
[XmlElement("month")]
public int Month { get; set; }
[XmlElement("year")]
public int Year { get; set; }
[XmlElement("yday")]
public int Yesterday { get; set; }
[XmlElement("hour")]
public int Hour { get; set; }
[XmlElement("min")]
public string Min { get; set; }
[XmlElement("sec")]
public int Sec { get; set; }
[XmlElement("isdst")]
public string Isdst { get; set; }
[XmlElement("monthname")]
public string MonthName { get; set; }
[XmlElement("monthname_short")]
public string MonthNameShort { get; set; }
[XmlElement("weekday_short")]
public string WeekdayShort { get; set; }
[XmlElement("weekday")]
public string Weekday { get; set; }
[XmlElement("ampm")]
public string AmPM { get; set; }
[XmlElement("tz_short")]
public string TzShort { get; set; }
[XmlElement("tz_long")]
public string TzLong { get; set; }
}
public class High
{
[XmlElement("fahrenheit")]
public string Fahrenheit { get; set; }
[XmlElement("celsius")]
public string Celsius { get; set; }
}
public class Low
{
[XmlElement("fahrenheit")]
public string Fahrenheit { get; set; }
[XmlElement("celsius")]
public string Celsius { get; set; }
}
public class QpfAllday
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("mm")]
public int Milimeters { get; set; }
}
public class QpfDay
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("mm")]
public int Milimeters { get; set; }
}
public class QpfNight
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("mm")]
public int Milimeters { get; set; }
}
public class SnowAllday
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("cm")]
public double Centimeters { get; set; }
}
public class SnowDay
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("cm")]
public double Centimeters { get; set; }
}
public class SnowNight
{
[XmlElement("#in")]
public double Inches { get; set; }
[XmlElement("cm")]
public double Centimeters { get; set; }
}
public class MaxWind
{
[XmlElement("mph")]
public int Mph { get; set; }
[XmlElement("kph")]
public int Kph { get; set; }
[XmlElement("dir")]
public string Direction { get; set; }
[XmlElement("degrees")]
public int Degrees { get; set; }
}
public class AveWind
{
[XmlElement("mph")]
public int Mph { get; set; }
[XmlElement("kph")]
public int Kph { get; set; }
[XmlElement("dir")]
public string Direction { get; set; }
[XmlElement("degrees")]
public int Degrees { get; set; }
}
Secondly, you need to deserialize XML into Response
using (HttpClient client = new HttpClient())
{
using (var stream = await client.GetStreamAsync("http://api.wunderground.com/api/ea4bb7e7839782da/forecast/q/CA/San_Francisco.xml"))
{
var serializer = new XmlSerializer(typeof(Response));
var response = (Response)serializer.Deserialize(stream);
var simpleForecast = response.Forecast.SimpleForecast;
var forecastDays = simpleForecast.ForecastDays;
var latestForecastDay = forecastDays.Last();
var latestHighFahrenheit = latestForecastDay.High.Fahrenheit;
var latestLowFahrenheit = latestForecastDay.Low.Fahrenheit;
}
}
I am using XmlSerializer but you can also use DataContractSerializer which is newer. If you decide to use DataContractSerializer keep in mind that you'll need to replace XmlElement attributes with DataContract and DataMember.
Note: I've intentionally added few unnecessary steps and variable declarations, so you can see clearly what's going on here.

json feed as a datasource in SSIS

I am trying to deserialize a json feed from openweathermap.org api. After a lot of tries all, using script transformation task, I get is errors and even different ones. Based on the below classes generated by JSON, how I should write the for each statements (as class Weather and Main are part of class RootObject)?
I can get even XML data from api, instead of JSON. Would it be easier to implement the process?
I am not asking for the answer, just a push to start.
JSON:
{
"coord":{
"lon":-122.08,
"lat":37.39
},
"weather":[
{
"id":741,
"main":"Fog",
"description":"fog",
"icon":"50n"
}
],
"base":"stations",
"main":{
"temp":286.14,
"pressure":1022,
"humidity":82,
"temp_min":285.15,
"temp_max":287.15
},
"visibility":16093,
"wind":{
"speed":1.11,
"deg":13.5055
},
"clouds":{
"all":1
},
"dt":1479110160,
"sys":{
"type":1,
"id":397,
"message":0.1452,
"country":"US",
"sunrise":1479134859,
"sunset":1479171466
},
"id":5375480,
"name":"Mountain View",
"cod":200
}
Class:
public class Coord
{
public double lon { get; set; }
public double lat { get; set; }
}
public class Weather
{
public int id { get; set; }
public string main { get; set; }
public string description { get; set; }
public string icon { get; set; }
}
public class Main
{
public double temp { get; set; }
public int pressure { get; set; }
public int humidity { get; set; }
public double temp_min { get; set; }
public double temp_max { get; set; }
}
public class Wind
{
public double speed { get; set; }
public double deg { get; set; }
}
public class Clouds
{
public int all { get; set; }
}
public class Sys
{
public int type { get; set; }
public int id { get; set; }
public double message { get; set; }
public string country { get; set; }
public int sunrise { get; set; }
public int sunset { get; set; }
}
public class RootObject
{
public Coord coord { get; set; }
public List<Weather> weather { get; set; }
public string #base { get; set; }
public Main main { get; set; }
public int visibility { get; set; }
public Wind wind { get; set; }
public Clouds clouds { get; set; }
public int dt { get; set; }
public Sys sys { get; set; }
public int id { get; set; }
public string name { get; set; }
public int cod { get; set; }
}

GeoJson c# example parse countries in the world and generate Geojson for each country

Looking for an example of how to parse / deserialize Geojson files using geojson.net. for some reason there are no examples of how to use the geojson.net package.
I would like to use this on my site with the google maps api. currently I use polygon shapes but want to move towards using geojson objects for the layers as this seems to be a better format.
using c# I would like to serialize Geojson, select specific country borders and generate a new geojson file that can be references and added to google maps as a layer.
to test this I created a colsole app to try to deserilaize the GeoJson, this does not work (please could you give me some direction on the correct way to deserialize Geojson ?)
static void Main(string[] args)
{
string Jsonstring = File.ReadAllText("c:/worldborders.json");
JavaScriptSerializer ser = new JavaScriptSerializer();
List<GeoJsonProperties> ns = (List<GeoJsonProperties>)ser.Deserialize(Jsonstring, typeof(List<GeoJsonProperties>));
?ns is Empty?
}
I created a class for the geojson file using the online generator http://json2csharp.com/ (I had thought that GeoJson.net would include the class as its a standard) , GeoJsonProperties,
public class GeoJsonProperties
{
public int scalerank { get; set; }
public string featurecla { get; set; }
public double labelrank { get; set; }
public string sovereignt { get; set; }
public string sov_a3 { get; set; }
public double adm0_dif { get; set; }
public double level { get; set; }
public string type { get; set; }
public string admin { get; set; }
public string adm0_a3 { get; set; }
public double geou_dif { get; set; }
public string geounit { get; set; }
public string gu_a3 { get; set; }
public double su_dif { get; set; }
public string subunit { get; set; }
public string su_a3 { get; set; }
public double brk_diff { get; set; }
public string name { get; set; }
public string name_long { get; set; }
public string brk_a3 { get; set; }
public string brk_name { get; set; }
public object brk_group { get; set; }
public string abbrev { get; set; }
public string postal { get; set; }
public string formal_en { get; set; }
public string formal_fr { get; set; }
public string note_adm0 { get; set; }
public string note_brk { get; set; }
public string name_sort { get; set; }
public string name_alt { get; set; }
public double mapcolor7 { get; set; }
public double mapcolor8 { get; set; }
public double mapcolor9 { get; set; }
public double mapcolor13 { get; set; }
public double pop_est { get; set; }
public double gdp_md_est { get; set; }
public double pop_year { get; set; }
public double lastcensus { get; set; }
public double gdp_year { get; set; }
public string economy { get; set; }
public string income_grp { get; set; }
public double wikipedia { get; set; }
public object fips_10 { get; set; }
public string iso_a2 { get; set; }
public string iso_a3 { get; set; }
public string iso_n3 { get; set; }
public string un_a3 { get; set; }
public string wb_a2 { get; set; }
public string wb_a3 { get; set; }
public double woe_id { get; set; }
public string adm0_a3_is { get; set; }
public string adm0_a3_us { get; set; }
public double adm0_a3_un { get; set; }
public double adm0_a3_wb { get; set; }
public string continent { get; set; }
public string region_un { get; set; }
public string subregion { get; set; }
public string region_wb { get; set; }
public double name_len { get; set; }
public double long_len { get; set; }
public double abbrev_len { get; set; }
public double tiny { get; set; }
public double homepart { get; set; }
}
public class Geometry
{
public string type { get; set; }
public List<List<List<object>>> coordinates { get; set; }
}
public class Feature
{
public string type { get; set; }
public GeoJsonProperties properties { get; set; }
public Geometry geometry { get; set; }
}
public class RootObject
{
public string type { get; set; }
public List<Feature> features { get; set; }
}
}
GeoJSON.Net works with Newtonsoft.Json. you can deserialize the same way you would using that library.
var geoJsonObject = JsonConvert.DeserializeObject<Point>(json);
For deserializing a FeatureCollection object (like the one you mention in the question) using the GeoJSON.Net library use the following code :
var collection = JsonConvert.DeserializeObject<FeatureCollection>(json);

Categories

Resources