Unity NewtonSoft Deserialization doesn't work in Build? - c#

my project is working fine in play mode from Unity.
But in my Build, it is not working. I'm getting an error from my JSON deserializer:
JsonSerializationException: Unable to find a constructor to use for type POIListCollection. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'pois', line 2, position 9.
But I have a constructor:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
public class POIListCollection
{
public PointOfInterest[] pois { get; set; }
[JsonConstructor]
public POIListCollection(PointOfInterest[] pois) {
this.pois = pois;
}
/**
* Also tried:
* public POIListCollection() {
*
* }
*
*/
}
I couldn't find a solution online.
So what's wrong here?
I'd be very grateful for any answers!
Edit: As requested the JSON:
And also the PointOfInterest Class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Newtonsoft.Json;
[System.Serializable]
public class PointOfInterest
{
[JsonIgnore]
public Color color { get; set; }
[JsonIgnore]
public Geoposition location { get; set; }
public string name { get; set; }
public string category { get; set; }
public string spritepath { get; set; }
public bool isTemporal { get; set; }
public double lat { get; set; }
public double lon { get; set; }
public bool openStatus { get; set; }
public int openTime { get; set; }
public int closeTime { get; set; }
public double rating { get; set; }
public double cost { get; set; }
public double chargeSartionDistance { get; set; }
public string[] tags { get; set; }
public PointOfInterest (string name, string category, string spritepath, bool isTemporal, double lat, double lon, bool openStatus, double rating, string[] tags, double cost, double chargeStationDistance, int closeTime, int openTime) {
this.name = name;
this.category = category;
this.spritepath = spritepath;
this.isTemporal = isTemporal;
this.lat = lat;
this.lon = lon;
this.openStatus = openStatus;
this.rating = rating;
this.tags = tags;
this.chargeSartionDistance = chargeStationDistance;
this.cost = cost;
this.closeTime = closeTime;
this.openTime = openTime;
}
}

Related

Parsing Open Weather Map API response fails [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I have this snippet of code:
public void getForcast()
{
string url = string.Format("https://samples.openweathermap.org/data/2.5/weather?q=London&appid=b6907d289e10d714a6e88b30761fae22");
using (WebClient web = new WebClient())
{
var json = web.DownloadString(url);
var obj = JsonConvert.DeserializeObject<WeatherData.WeatherForcast>(json);
WeatherData.WeatherForcast forcast = obj;
WeatherMark.Text = string.Format("{0}", forcast.list[1].weathers[0].description);
}
}
I want it to get description of it from forecast list.
But instead I'm getting this error
Object reference not set to an instance of an object
here's my whole list of classes:
class WeatherForcast
{
public List<list> list { get; set; }
}
public class weather
{
public string main { get; set; }
public string description { get; set; }
}
public class list
{
public List<weather> weathers { get; set; }
}
anyone knows why does it appear?
The JSON most likely does not match the provided class definition which results in a null object when parsed.
Calling the shown URL in a browser provides the following JSON response
{"coord":{"lon":-0.13,"lat":51.51},"weather":[{"id":300,"main":"Drizzle","description":"light
intensity
drizzle","icon":"09d"}],"base":"stations","main":{"temp":280.32,"pressure":1012,"humidity":81,"temp_min":279.15,"temp_max":281.15},"visibility":10000,"wind":{"speed":4.1,"deg":80},"clouds":{"all":90},"dt":1485789600,"sys":{"type":1,"id":5091,"message":0.0103,"country":"GB","sunrise":1485762037,"sunset":1485794875},"id":2643743,"name":"London","cod":200}
Which can be mapped to your shown code already provided with some modification.
public class WeatherForcast {
public List<weather> weather { get; set; }
}
public class weather {
public string main { get; set; }
public string description { get; set; }
}
There are online tools available where you can place the JSON and it will generate the mapped classes for the JSON.
You can get weather in Xml using &mode=xml and then use xml serialization :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string URL = "https://samples.openweathermap.org/data/2.5/weather?q=London&mode=xml&appid=b6907d289e10d714a6e88b30761fae22";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(URL);
XmlSerializer serializer = new XmlSerializer(typeof(Weather));
Weather weather = (Weather)serializer.Deserialize(reader);
}
}
[XmlRoot("current")]
public class Weather
{
public City city { get; set; }
public Temperature temperature { get; set; }
public Humidity humidity { get; set; }
public Pressure pressure { get; set; }
public Wind wind { get; set; }
}
public class City
{
[XmlAttribute()]
public string name { get; set; }
[XmlAttribute()]
public string id { get; set; }
public Coord coord { get; set; }
public string country { get; set; }
public Sun sun { get; set; }
}
public class Sun
{
[XmlAttribute()]
public DateTime rise { get; set; }
[XmlAttribute()]
public DateTime set { get; set; }
}
public class Coord
{
[XmlAttribute()]
public decimal lon { get; set; }
[XmlAttribute()]
public decimal lat { get; set; }
}
public class Temperature
{
[XmlAttribute()]
public decimal value { get; set; }
[XmlAttribute()]
public decimal min { get; set; }
[XmlAttribute()]
public decimal max { get; set; }
}
public class Humidity
{
[XmlAttribute()]
public decimal value { get; set; }
}
public class Pressure
{
[XmlAttribute()]
public decimal value { get; set; }
}
public class Wind
{
public Speed speed { get; set; }
public Direction direction { get; set; }
}
public class Speed
{
[XmlAttribute()]
public decimal value { get; set; }
[XmlAttribute()]
public string name { get; set; }
}
public class Direction
{
[XmlAttribute()]
public decimal value { get; set; }
[XmlAttribute()]
public string name { get; set; }
[XmlAttribute()]
public string code { get; set; }
}
}

Deserializing JSON data to C#

Could U help me Deserializing JSON to C#? I just eat my teeth on it.. =.=.
I find many methods how to do not solve this xD,
I dont want share that with U.
I wish to wait for your suggestions.
Usefull links:
http://jsonviewer.stack.hu/
http://json2csharp.com/
JSON looks..
[
{
"faceId":"626f5974-1d63-40d4-98f1-7e6a7df13dba",
"faceRectangle":{
"top":108,
"left":699,
"width":208,
"height":208
},
"faceAttributes":{
"smile":0.973,
"gender":"male",
"age":25.7,
"emotion":{
"anger":0.0,
"contempt":0.026,
"disgust":0.0,
"fear":0.0,
"happiness":0.973,
"neutral":0.001,
"sadness":0.0,
"surprise":0.0
}
}
},
{
"faceId":"bc051f1d-9a64-4e86-bf95-2af1de21d316",
"faceRectangle":{
"top":104,
"left":634,
"width":114,
"height":114
},
"faceAttributes":{
"smile":0.074,
"gender":"male",
"age":17.4,
"emotion":{
"anger":0.003,
"contempt":0.003,
"disgust":0.001,
"fear":0.002,
"happiness":0.074,
"neutral":0.828,
"sadness":0.079,
"surprise":0.01
}
}
}
]
First of all you need classes to which you want to deserialize, so you can create manually or the fastest and easiest way - you can copy json string that you have, then in visual studio
Edit -> Paste Special -> Paste JSON as Classes
Now you have structure for deserializing.Then you can for example use Newtonsoft.Json (which you can download from NuGet). There is JsonConvert.DeserializeObject<T>() generic method, that will do all deserialization work for you.
Also, if you want use your own property names in the class structure, you can use [JsonProperty("Name")] attribute, which will change the names of properties when they are serialized to JSON and vice versa.
Your JSON document represents an array so you must deserialize it to a collection
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
string jsonString = "[ {\"faceId\": \"626f5974-1d63-40d4-98f1-7e6a7df13dba\",\"faceRectangle\": { \"top\": 108, \"left\": 699, \"width\": 208, \"height\": 208 },\"faceAttributes\": { \"smile\": 0.973, \"gender\": \"male\", \"age\": 25.7, \"emotion\": { \"anger\": 0.0, \"contempt\": 0.026, \"disgust\": 0.0, \"fear\": 0.0, \"happiness\": 0.973, \"neutral\": 0.001, \"sadness\": 0.0, \"surprise\": 0.0 } }},{\"faceId\": \"bc051f1d-9a64-4e86-bf95-2af1de21d316\",\"faceRectangle\": { \"top\": 104, \"left\": 634, \"width\": 114, \"height\": 114 },\"faceAttributes\": { \"smile\": 0.074, \"gender\": \"male\", \"age\": 17.4, \"emotion\": { \"anger\": 0.003, \"contempt\": 0.003, \"disgust\": 0.001, \"fear\": 0.002, \"happiness\": 0.074, \"neutral\": 0.828, \"sadness\": 0.079, \"surprise\": 0.01 } }}]";
var result = JsonConvert.DeserializeObject<IList<RootObject>>(jsonString);
foreach ( var item in result )
Console.WriteLine( item.faceId );
}
}
// Generated by http://json2csharp.com
public class FaceRectangle
{
public int top { get; set; }
public int left { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Emotion
{
public double anger { get; set; }
public double contempt { get; set; }
public double disgust { get; set; }
public double fear { get; set; }
public double happiness { get; set; }
public double neutral { get; set; }
public double sadness { get; set; }
public double surprise { get; set; }
}
public class FaceAttributes
{
public double smile { get; set; }
public string gender { get; set; }
public double age { get; set; }
public Emotion emotion { get; set; }
}
public class RootObject
{
public string faceId { get; set; }
public FaceRectangle faceRectangle { get; set; }
public FaceAttributes faceAttributes { get; set; }
}
.net fiddle
If you want c# object from that JSON, this is how it is done:
public class FaceRectangle
{
public int top { get; set; }
public int left { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Emotion
{
public double anger { get; set; }
public double contempt { get; set; }
public double disgust { get; set; }
public double fear { get; set; }
public double happiness { get; set; }
public double neutral { get; set; }
public double sadness { get; set; }
public double surprise { get; set; }
}
public class FaceAttributes
{
public double smile { get; set; }
public string gender { get; set; }
public double age { get; set; }
public Emotion emotion { get; set; }
}
public class RootObject
{
public string faceId { get; set; }
public FaceRectangle faceRectangle { get; set; }
public FaceAttributes faceAttributes { get; set; }
}
var obj = JsonConvert.DeserializeObject<RootObject>(json);
Instead of giving you a C# class that maps to the JSON which you'll just copy blindly, I'll recommend that you generate such a class yourself.
Make sure you're running Visual Studio 2013 SP2 or higher.
Get a JSON document for your data. If it has optional fields, make sure the one you have is as full as possible.
In a new CS file in VS, choose Edit -> Paste Special -> Paste JSON as Classes.
This will create a C# class that corresponds to the JSON data. Now, you can use JSON.NET's JsonConvert.DeserializeObject() to create it
By using NewtonsoftJson library to parse data easily
Example
dynamic x = Newtonsoft.Json.JsonConvert.DeserializeObject(Jsondata); //to parse data
foreach (var product in x) {
Messagebox.show(product.data.ToString());
}
You can convert Json to c# Class
public class FaceRectangle
{
public int top { get; set; }
public int left { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Emotion
{
public double anger { get; set; }
public double contempt { get; set; }
public double disgust { get; set; }
public double fear { get; set; }
public double happiness { get; set; }
public double neutral { get; set; }
public double sadness { get; set; }
public double surprise { get; set; }
}
public class FaceAttributes
{
public double smile { get; set; }
public string gender { get; set; }
public double age { get; set; }
public Emotion emotion { get; set; }
}
public class Example
{
public string faceId { get; set; }
public FaceRectangle faceRectangle { get; set; }
public FaceAttributes faceAttributes { get; set; }
}
Example Example_class =
Newtonsoft.Json.JsonConvert.DeserializeObject<Example>(json.ToString());
Please see this useful link Json to C# Class https://jsonutils.com/
Do you mean something like this? To deserialize to an object?
using System.Web.Script.Serialization;
public class FaceRectangle
{
public int top { get; set; }
public int left { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Emotion
{
public double anger { get; set; }
public double contempt { get; set; }
public double disgust { get; set; }
public double fear { get; set; }
public double happiness { get; set; }
public double neutral { get; set; }
public double sadness { get; set; }
public double surprise { get; set; }
}
public class FaceAttributes
{
public double smile { get; set; }
public string gender { get; set; }
public double age { get; set; }
public Emotion emotion { get; set; }
}
public class RootObject
{
public string faceId { get; set; }
public FaceRectangle faceRectangle { get; set; }
public FaceAttributes faceAttributes { get; set; }
}
return JsonConvert.DeserializeObject<RootObject>(jsonString);
I hope this will work
string Jsondata = "Your Json data";
public class Mainclass
{
public guid faceId;
IEnumerable<faceRectangle>
IEnumerable<faceAttributes>
}
public class faceRectangle
{
}
public class faceAttributes
{
}
Mainclass backdata = JsonConvert.DeserializeObject<Mainclass>(Jsondata , new DataConverter())

Web API not parsing get parameters correctly

I have the following url
http://localhost/api/map/tmc/identify?
geometry={x:-112.0469856262207,y:33.3926093953406, spatialReference:{wkid:4326}}
&geometryType=esriGeometryPoint
&mapExtent={xmin:-112.18062400817871,ymin:33.33956359362892,xmax:-111.95076942443848,ymax:33.49201883920683, spatialReference:{wkid:4326}}
&tolerance=5
&sr=4326
&imageDisplay=1340,1065,96
&layers=all:0
&returnGeometry=true
&returnM=false
I am trying to intercept that object using the following action
public class SpatialReference
{
public int wkid { get; set; }
}
public class Geometry
{
public double x { get; set; }
public double y { get; set; }
public SpatialReference spatialReference { get; set; }
}
public class MapExtent
{
public double xmin { get; set; }
public double ymin { get; set; }
public double xmax { get; set; }
public double ymax { get; set; }
public SpatialReference spatialReference { get; set; }
}
public class RootObject
{
public Geometry geometry { get; set; }
public string geometryType { get; set; }
public MapExtent mapExtent { get; set; }
public int tolerance { get; set; }
public int sr { get; set; }
public List<int> imageDisplay { get; set; }
public string layers { get; set; }
public bool returnGeometry { get; set; }
public bool returnM { get; set; }
}
[HttpGet]
[Route("api/map/tmc/identify")]
public object Identify([FromUri]RootObject root)
{
return root;
}
And I get back
{
"geometry":{
"x":0.0,
"y":0.0,
"spatialReference":null
},
"geometryType":"esriGeometryPoint",
"mapExtent":{
"xmin":0.0,
"ymin":0.0,
"xmax":0.0,
"ymax":0.0,
"spatialReference":null
},
"tolerance":5,
"sr":4326,
"imageDisplay":[
0
],
"layers":"all:0",
"returnGeometry":true,
"returnM":false
}
as you can see the tolerance and sr were set correctly but the objects were not. Unfortunately I have no control over the request (It's always a GET and in this format). How can I correctly parse the url into the right objects
Since you have 9 query parameters in your http GET, you should declare 9 arguments in the action method instead of a root object i.e:
[HttpGet]
[Route("api/map/tmc/identify")]
public object Identify([FromUri]Geometry geometry,
[FromUri]string geometryType,
[FromUri] MapExtent mapExtent,
...)
[FromUri]RootObject root will not map the parameters correctly since they are query parameters and not a POST body

get data from json c#

I have a problem I want to get data from Json, and the data
successfully gets from the json to the variable json but when I want to send the data to WeatherData it send me a zero value.
I have one class that cald "WeatherData" and I want to send to data from the json (that existing a class "jsonParse") to this class.
jsonParse
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Web.Script.Serialization;
using System.IO;
namespace weather
{
public class jsonParse : Ijson
{
private string urlAdd;
public jsonParse(string _url)
{
if (_url == null)
{
//throw exption
}
else
urlAdd = _url;
}
public WeatherData parse()
{
//string json = new WebClient().DownloadString(urlAdd);
//var obj = JsonConvert.DeserializeObject<WeatherData>(json);
//Console.WriteLine(obj.temp);
// WeatherData m = JsonConvert.DeserializeObject<WeatherData>(json);
WebClient n = new WebClient();
var json = n.DownloadString(urlAdd);
string valueOriginal = Convert.ToString(json);
WeatherData m = JsonConvert.DeserializeObject<WeatherData>(json);
Console.WriteLine(m);
return m;
}
}
}
WeatherData
namespace weather
{
public class WeatherData
{
public WeatherData(double _temp, double _minTemp, double _maxTemp )
{
temp = _temp;
minTemp = _minTemp;
maxTemp = _maxTemp;
}
public double temp { get; set; }
public double minTemp { get; set; }
public double maxTemp { get; set; }
public override string ToString()
{
return "the weather:" + temp + "minTemp is:" + minTemp + "maxTemp:" + maxTemp;
}
}
}
json
{"coord":{"lon":139,"lat":35},
"sys":{"country":"JP","sunrise":1369769524,"sunset":1369821049},
"weather":[{"id":804,"main":"clouds","description":"overcast clouds","icon":"04n"}],
"main":{"temp":289.5,"humidity":89,"pressure":1013,"temp_min":287.04,"temp_max":292.04},
"wind":{"speed":7.31,"deg":187.002},
"rain":{"3h":0},
"clouds":{"all":92},
"dt":1369824698,
"id":1851632,
"name":"Shuzenji",
"cod":200}
If you only care about the weather part of the json, try this -
var o = (JArray)JObject.Parse(jsonString)["weather"];
foreach(JToken item in o)
{
Console.WriteLine(((JValue)item["id"]).Value);
Console.WriteLine(((JValue)item["main"]).Value);
Console.WriteLine(((JValue)item["description"]).Value);
Console.WriteLine(((JValue)item["icon"]).Value);
}
First object in json is coord, don't see that in your model.
You should change your JsonModel to deserialize. From c# class generator:
public class Coord
{
public int lon { get; set; }
public int lat { get; set; }
}
public class Sys
{
public string country { get; set; }
public int sunrise { get; set; }
public int sunset { 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 humidity { get; set; }
public int pressure { 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 Rain
{
public int __invalid_name__3h { get; set; }
}
public class Clouds
{
public int all { get; set; }
}
public class RootObject
{
public Coord coord { get; set; }
public Sys sys { get; set; }
public List<Weather> weather { get; set; }
public Main main { get; set; }
public Wind wind { get; set; }
public Rain rain { get; set; }
public Clouds clouds { get; set; }
public int dt { get; set; }
public int id { get; set; }
public string name { get; set; }
public int cod { get; set; }
}
Where RootObject is your JsonConvert.DeserializeObject(json);
So you can change class names as you like.
Simply you cannot Deserialize a json object to a non-matching class object. So make sure you have a model object that have atleast all the properties that JSON object have.
In this case you would need following classes that are generated from your JSON object:
public class Coord
{
public int lon { get; set; }
public int lat { get; set; }
}
public class Sys
{
public string country { get; set; }
public int sunrise { get; set; }
public int sunset { 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 humidity { get; set; }
public int pressure { 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 Rain
{
public int __invalid_name__3h { get; set; }
}
public class Clouds
{
public int all { get; set; }
}
public class ParentModel
{
public Coord coord { get; set; }
public Sys sys { get; set; }
public List<Weather> weather { get; set; }
public Main main { get; set; }
public Wind wind { get; set; }
public Rain rain { get; set; }
public Clouds clouds { get; set; }
public int dt { get; set; }
public int id { get; set; }
public string name { get; set; }
public int cod { get; set; }
}
ParentModel m = JsonConvert.DeserializeObject<ParentModel>(json);
Hope this helps.

Getting Exception when trying to retrieve data from "OpenWeatherMap.org" [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
I am currently working on Weather API in which I am trying to take values from OpenWeatherMap.org. But When I click the button to retrieve the information from the website. It gives me the following Error.Here's the Screenshot of the exception,I am Getting
Also Here's the UI for Button I am clicking.
System.Exception was unhandled by user code
HResult=-2146233088
Message=Exception of type 'System.Exception' was thrown.
Source=UWPWeather
StackTrace:
at UWPWeather.LocationManager.<GetPosition>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at UWPWeather.MainPage.<Button_Click>d__1.MoveNext()
InnerException:
The OpenWeatherMapProxy.cs code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
namespace WeatherAPI
{
public class OpenWeatherMapProxy
{
public async static Task<RootObject>GetWeather(double lat,double lon)
{
var http = new HttpClient();
var response = await http.GetAsync("http://api.openweathermap.org/data/2.5/weather? lat=35&lon=77.20081&appid=b1b15e88fa797225412429c1c50c122a");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)serializer.ReadObject(ms);
return data;
}
}
public class Coord
{
[DataMember]
public double lon { get; set; }
[DataMember]
public double lat { get; set; }
}
[DataContract]
public class Weather
{
[DataMember]
public int id { get; set; }
[DataMember]
public string main { get; set; }
[DataMember]
public string description { get; set; }
[DataMember]
public string icon { get; set; }
}
[DataContract]
public class Main
{
[DataMember]
public double temp { get; set; }
[DataMember]
public int pressure { get; set; }
[DataMember]
public int humidity { get; set; }
[DataMember]
public double temp_min { get; set; }
[DataMember]
public double temp_max { get; set; }
}
[DataContract]
public class Wind
{
[DataMember]
public double speed { get; set; }
[DataMember]
public int deg { get; set; }
}
[DataContract]
public class Clouds
{
[DataMember]
public int all { get; set; }
}
[DataContract]
public class Sys
{
[DataMember]
public int type { get; set; }
[DataMember]
public int id { get; set; }
[DataMember]
public double message { get; set; }
[DataMember]
public string country { get; set; }
[DataMember]
public int sunrise { get; set; }
[DataMember]
public int sunset { get; set; }
}
[DataContract]
public class RootObject
{
[DataMember]
public Coord coord { get; set; }
[DataMember]
public List<Weather> weather { get; set; }
[DataMember]
public string #base { get; set; }
[DataMember]
public Main main { get; set; }
[DataMember]
public Wind wind { get; set; }
[DataMember]
public Clouds clouds { get; set; }
[DataMember]
public int dt { get; set; }
[DataMember]
public Sys sys { get; set; }
[DataMember]
public int id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public int cod { get; set; }
}
MainPage.xaml.cs code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace WeatherAPI
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
RootObject myWeather = await OpenWeatherMapProxy.GetWeather(20.0,30.0);
ResultTextBlock.Text = myWeather.name + " - " + ((int)myWeather.main.temp).ToString();
}
}
}
Here's the code running (it is running a console application):
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
public class OpenWeatherMapProxy
{
public async static Task<RootObject> GetWeather(double lat, double lon)
{
var http = new HttpClient();
var response = await http.GetAsync("http://api.openweathermap.org/data/2.5/weather?lat=35&lon=77.20081&appid=b1b15e88fa797225412429c1c50c122a");
var result = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)serializer.ReadObject(ms);
return data;
}
}
public class Coord
{
[DataMember]
public double lon { get; set; }
[DataMember]
public double lat { get; set; }
}
[DataContract]
public class Weather
{
[DataMember]
public double id { get; set; }
[DataMember]
public string main { get; set; }
[DataMember]
public string description { get; set; }
[DataMember]
public string icon { get; set; }
}
[DataContract]
public class Main
{
[DataMember]
public double temp { get; set; }
[DataMember]
public double pressure { get; set; }
[DataMember]
public double humidity { get; set; }
[DataMember]
public double temp_min { get; set; }
[DataMember]
public double temp_max { get; set; }
}
[DataContract]
public class Wind
{
[DataMember]
public double speed { get; set; }
[DataMember]
public double deg { get; set; }
}
[DataContract]
public class Clouds
{
[DataMember]
public double all { get; set; }
}
[DataContract]
public class Sys
{
[DataMember]
public double type { get; set; }
[DataMember]
public double id { get; set; }
[DataMember]
public double message { get; set; }
[DataMember]
public string country { get; set; }
[DataMember]
public double sunrise { get; set; }
[DataMember]
public double sunset { get; set; }
}
[DataContract]
public class RootObject
{
[DataMember]
public Coord coord { get; set; }
[DataMember]
public List<Weather> weather { get; set; }
[DataMember]
public string #base { get; set; }
[DataMember]
public Main main { get; set; }
[DataMember]
public Wind wind { get; set; }
[DataMember]
public Clouds clouds { get; set; }
[DataMember]
public double dt { get; set; }
[DataMember]
public Sys sys { get; set; }
[DataMember]
public double id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public double cod { get; set; }
}
class Program
{
static void Main(string[] args)
{
RootObject myWeather = Task.Run(() => OpenWeatherMapProxy.GetWeather(20.0, 30.0)).Result;
Console.WriteLine( myWeather.name + " - " + ((int)myWeather.main.temp).ToString());
}
}
((int)myWeather.main.temp).ToString()
I have to ask: Why to int and then back to string again??
Anyways, the answer to your problem:
You need to check that myWeather != null && myWeather.main != null && myWeather.main.temp != null
One of them is null, which is giving you the exception.

Categories

Resources