Very slow downloading data to app - c#

I writing uwp app.
I try to download json and display data.
I send to method lan and lon variables, put it and link and download data.
Location code:
public class LocationManager
{
public async static Task<Geoposition> GetPosition()
{
var accessStatus = await Geolocator.RequestAccessAsync();
if (accessStatus != GeolocationAccessStatus.Allowed) throw new Exception();
var geolocator = new Geolocator { DesiredAccuracyInMeters = 0 };
var position = await geolocator.GetGeopositionAsync();
return position;
}
}
Downloading JSON code:
private const string APPID = "f3c45b5a19426de9ea6ba7eb6c6969d7";
public async static Task<RootObject> GetWeather(double lat, double lon)
{
var http = new HttpClient();
var url = String.Format(
"http://api.openweathermap.org/data/2.5/weather?lat={0}&lon={1}&units=metric&APPID="+APPID, lat, lon);
var response = await http.GetAsync(url);
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;
}
}
[DataContract]
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 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 Rain
{
[DataMember]
public double __invalid_name__1h { 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 Rain rain { 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; }
}
and there I show data like this:
public async void WeatherDisplay()
{
try
{
//var position = await LocationManager.GetPosition();
var geoLocator = new Geolocator();
geoLocator.DesiredAccuracy = PositionAccuracy.High;
Geoposition pos = await geoLocator.GetGeopositionAsync();
var lat = pos.Coordinate.Point.Position.Latitude;
var lon = pos.Coordinate.Point.Position.Longitude;
RootObject myWeather =
await OpenWeatherMapProxy.GetWeather(
lat,
lon);
Temperature.Text = ((int)myWeather.main.temp).ToString() + "°C";
// DescriptionTextBlock.Text = myWeather.weather[0].description;
City.Text = myWeather.name;
}
catch
{
}
}
My trouble in delays, I tap button and it show data in 30-40 seconds. With internet all okay. Why I have such big delays?

Related

How to parse "temp" from Json in C#?

I need to get "temp", name and description out of this JSON format. I can get some of these out but not all, I went through the questions but I could not get a specific answer.
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(string.Format("https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=XXX"));
WebReq.Method = "GET";
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
Console.WriteLine(WebResp.StatusCode);
Console.WriteLine(WebResp.Server);
string jsonString;
//modified from your code since the using statement disposes the stream
//automatically when done
using (Stream stream = WebResp.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8);
jsonString = reader.ReadToEnd();
}
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(jsonString);
foreach (var item in obj)
{
}
JSON FORMAT:
{
"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
}
You will need to use Json.NET (NuGet). Then, create a model for the json, you can use some online tools like QuickType and Json Editor Online to help you converting Json to Object. Then, use the model with the Json.NET to Deserialize it (in other word, mapping the Json to the Model).
Then, use the new created object to access the json values.
Here is an example of your Json (Using Json.NET):
Model :
public class WeatherCast
{
[JsonProperty("coord")]
public Coord Coord { get; set; }
[JsonProperty("weather")]
public Weather[] Weather { get; set; }
[JsonProperty("base")]
public string Base { get; set; }
[JsonProperty("main")]
public Main Main { get; set; }
[JsonProperty("visibility")]
public long Visibility { get; set; }
[JsonProperty("wind")]
public Wind Wind { get; set; }
[JsonProperty("clouds")]
public Clouds Clouds { get; set; }
[JsonProperty("dt")]
public long Dt { get; set; }
[JsonProperty("sys")]
public Sys Sys { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("cod")]
public long Cod { get; set; }
}
public class Weather
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("main")]
public string Main { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("icon")]
public string Icon { get; set; }
}
public class Clouds
{
[JsonProperty("all")]
public long All { get; set; }
}
public class Coord
{
[JsonProperty("lon")]
public double Lon { get; set; }
[JsonProperty("lat")]
public double Lat { get; set; }
}
public class Main
{
[JsonProperty("temp")]
public double Temp { get; set; }
[JsonProperty("pressure")]
public long Pressure { get; set; }
[JsonProperty("humidity")]
public long Humidity { get; set; }
[JsonProperty("temp_min")]
public double TempMin { get; set; }
[JsonProperty("temp_max")]
public double TempMax { get; set; }
}
public class Sys
{
[JsonProperty("type")]
public long Type { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("message")]
public double Message { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("sunrise")]
public long Sunrise { get; set; }
[JsonProperty("sunset")]
public long Sunset { get; set; }
}
public class Wind
{
[JsonProperty("speed")]
public double Speed { get; set; }
[JsonProperty("deg")]
public long Deg { get; set; }
}
Then, using Json.NET you do this :
var json = "{\"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}";
var forecast = JsonConvert.DeserializeObject<WeatherCast>(json);
var temp = forecast.Main.Temp;
var name = forecast.Name;
var description = forecast.Weather[0].Description;

C# Deserialize json api response

hey i want to Deserialize this json API response to get values including profile state etc for processing in the program.
i tried multiple ways from different questions in here but i get response as null.
here is the code, correct me what i am doing wrong please
{
"response": {
"players": [{
"steamid": "xxxxxxxxxxxxxxxxx",
"communityvisibilitystate": 3,
"profilestate": 1,
"personaname": "xxxx xxxx",
"lastlogoff": 1529478555,
"commentpermission": 1,
"profileurl": "xxxxxxxxxxxxxxx",
"avatar": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"avatarmedium": "xxxxxxxxxxxxxxxxxxxxx",
"avatarfull": "xxxxxxxxxxx",
"personastate": 1,
"realname": "xxxx",
"primaryclanid": "xxxxxxxxxx",
"timecreated": 1097464215,
"personastateflags": 0
}]
}
}
The code i tried
public class AccountInfo
{
public string steamid { get; set; }
public int communityvisibilitystate { get; set; }
public int profilestate { get; set; }
public string personaname { get; set; }
public ulong lastlogoff { get; set; }
public int commentpermission { get; set; }
public string profileurl { get; set; }
public string avatar { get; set; }
public string avatarmedium { get; set; }
public string avatarfull { get; set; }
public int personastate { get; set; }
public string realname { get; set; }
public string primaryclanid { get; set; }
public ulong timecreated { get; set; }
public int personastateflags { get; set; }
}
public class Response
{
public AccountInfo response { get; set; }
}
public class Response1
{
public Response players { get; set; }
}
static void Main(string[] args)
{
DeserilizeJson();
}
internal static void DeserilizeJson()
{
string json = GetUrlToString("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=xxxxxxxxxxxxxxxxxxxxx&steamids=xxxxxxxxxxxxxxx");
Console.WriteLine(json);
Response1 info = JsonConvert.DeserializeObject<Response1>(json);
using (StreamWriter file = File.CreateText(#"c:\test.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, info);
}
}
internal static string GetUrlToString(string url)
{
String Response = null;
try
{
using (WebClient client = new WebClient())
{
Response = client.DownloadString(url);
}
}
catch (Exception)
{
return null;
}
return Response;
}
Use this as a Model Class
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class JsonModel
{
[JsonProperty("response")]
public Response Response { get; set; }
}
public partial class Response
{
[JsonProperty("players")]
public List<Player> Players { get; set; }
}
public partial class Player
{
[JsonProperty("steamid")]
public string Steamid { get; set; }
[JsonProperty("communityvisibilitystate")]
public long Communityvisibilitystate { get; set; }
[JsonProperty("profilestate")]
public long Profilestate { get; set; }
[JsonProperty("personaname")]
public string Personaname { get; set; }
[JsonProperty("lastlogoff")]
public long Lastlogoff { get; set; }
[JsonProperty("commentpermission")]
public long Commentpermission { get; set; }
[JsonProperty("profileurl")]
public string Profileurl { get; set; }
[JsonProperty("avatar")]
public string Avatar { get; set; }
[JsonProperty("avatarmedium")]
public string Avatarmedium { get; set; }
[JsonProperty("avatarfull")]
public string Avatarfull { get; set; }
[JsonProperty("personastate")]
public long Personastate { get; set; }
[JsonProperty("realname")]
public string Realname { get; set; }
[JsonProperty("primaryclanid")]
public string Primaryclanid { get; set; }
[JsonProperty("timecreated")]
public long Timecreated { get; set; }
[JsonProperty("personastateflags")]
public long Personastateflags { get; set; }
}
Then do this in your Main Class
var info = JsonConvert.DeserializeObject<JsonModel>(json);
var Response = info.Response
Open nuget, search newtonsoft.json and install.
Deserialize:
var deserialized = JsonConvert.DeserializeObject(jsonstring);
Try this:
public class Player
{
public string steamid { get; set; }
public int communityvisibilitystate { get; set; }
public int profilestate { get; set; }
public string personaname { get; set; }
public ulong lastlogoff { get; set; }
public int commentpermission { get; set; }
public string profileurl { get; set; }
public string avatar { get; set; }
public string avatarmedium { get; set; }
public string avatarfull { get; set; }
public int personastate { get; set; }
public string realname { get; set; }
public string primaryclanid { get; set; }
public ulong timecreated { get; set; }
public int personastateflags { get; set; }
}
public class Response
{
public Player[] players { get; set; }
}
public class EncapsulatedResponse
{
public Response response {get;set;}
}
internal static void DeserilizeJson()
{
string json = GetUrlToString("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=xxxxxxxxxxxxxxxxxxxxx&steamids=xxxxxxxxxxxxxxx");
Console.WriteLine(json);
EncapsulatedResponse info = JsonConvert.DeserializeObject<EncapsulatedResponse>(json);
using (StreamWriter file = File.CreateText(#"c:\test.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, info);
}
}
The players property should be a list of players as it is an array . Below is the Correct Model
public class Player
{
public string steamid { get; set; }
public int communityvisibilitystate { get; set; }
public int profilestate { get; set; }
public string personaname { get; set; }
public int lastlogoff { get; set; }
public int commentpermission { get; set; }
public string profileurl { get; set; }
public string avatar { get; set; }
public string avatarmedium { get; set; }
public string avatarfull { get; set; }
public int personastate { get; set; }
public string realname { get; set; }
public string primaryclanid { get; set; }
public int timecreated { get; set; }
public int personastateflags { get; set; }
}
public class Response
{
public List<Player> players { get; set; }
}
You need to change the object structure:
public class Response
{
public AccountInfo[] players { get; set; }
}
public class Response1
{
public Response response { get; set; }
}
then deserialize Response1 (like u do currently)
Just to provide a different approach, you can use JObject (Newtonsoft.Json.Linq) so that you only need the AccountInfo class:
var accounts = JObject.Parse(json).Root
.SelectToken("response.players")
.ToObject(typeof(AccountInfo[]));
Or in some cases, it is even easier just navigating the properties:
var accounts = JObject.Parse(json)["response"]["players"]
.ToObject((typeof(AccountInfo[])));

UWP Get array from json Url

I'm using a class to get data from json to my main page and in my json i have an array i want to get them to my Main Page Here's my class code
class WeatherDays
{
public async static Task<day> GetWeather(double lat, double lon)
{
var http = new HttpClient();
var responce = await http.GetAsync("http://a3ane.com/omarNasar/d.php");
var result = await responce.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(day));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (day)serializer.ReadObject(ms);
return data;
}
}
[DataContract]
public class Omarnasar
{
[DataMember]
public string w_id { get; set; }
[DataMember]
public string w_note_tody { get; set; }
[DataMember]
public string w_date { get; set; }
[DataMember]
public string w_time { get; set; }
[DataMember]
public string w_tody_one { get; set; }
[DataMember]
public string w_temperature_one { get; set; }
[DataMember]
public string w_humidity_one { get; set; }
[DataMember]
public string w_note_one { get; set; }
[DataMember]
public string w_tody_two { get; set; }
[DataMember]
public string w_temperature_two { get; set; }
[DataMember]
public string w_humidity_two { get; set; }
[DataMember]
public string w_note_two { get; set; }
[DataMember]
}
[DataContract]
public class day
{
[DataMember]
public List<Omarnasar> omarnasar { get; set; }
}
}
and my problem is i don't know how to get then to my main page using the task here's my try on MainPage
day week = await WeatherDays.GetWeather(20.0, 30.0);
temp1.Text = week.omarnasr.
I don't know how to use them can anyone help my !!!
I think this is what you want
StringBuilder sb = new StringBuilder();
foreach(var obj in week.omarnasr)
{
sb.Append(obj.w_temperature_one + " ");
}
temp1.Text = sb.ToString();

C# JSON Get data from List<>

I am trying to make simple UWP weather app, just for learning purpose, and I am having trouble getting data from JSON.
How to get min and max temperature from public class ConsolidatedWeather?
I can get data from other classes.
Thanks a lot
Vrime.cs
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;
using Newtonsoft.Json;
namespace _01_Weaather
{
class Vrime
{
public async static Task<ConsolidatedWeather> ShowTemp()
{
var http = new HttpClient();
var url = String.Format("https://www.metaweather.com/api/location/44418/");
var response = await http.GetAsync(url);
var result = await response.Content.ReadAsStringAsync();
var ser = new DataContractJsonSerializer(typeof(ConsolidatedWeather));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (ConsolidatedWeather)ser.ReadObject(ms);
return data;
}
}
[DataContract]
public class ConsolidatedWeather
{
[DataMember]
public object id { get; set; }
[DataMember]
public string weather_state_name { get; set; }
[DataMember]
public string weather_state_abbr { get; set; }
[DataMember]
public string wind_direction_compass { get; set; }
[DataMember]
public string created { get; set; }
[DataMember]
public string applicable_date { get; set; }
[DataMember]
public double min_temp { get; set; }
[DataMember]
public double max_temp { get; set; }
[DataMember]
public double the_temp { get; set; }
[DataMember]
public double wind_speed { get; set; }
[DataMember]
public double wind_direction { get; set; }
[DataMember]
public double air_pressure { get; set; }
[DataMember]
public int humidity { get; set; }
[DataMember]
public double? visibility { get; set; }
[DataMember]
public int predictability { get; set; }
}
[DataContract]
public class Parent
{
[DataMember]
public string title { get; set; }
[DataMember]
public string location_type { get; set; }
[DataMember]
public int woeid { get; set; }
[DataMember]
public string latt_long { get; set; }
}
[DataContract]
public class Source
{
[DataMember]
public string title { get; set; }
[DataMember]
public string slug { get; set; }
[DataMember]
public string url { get; set; }
[DataMember]
public int crawl_rate { get; set; }
}
[DataContract]
public class RootObject
{[DataMember]
public List<ConsolidatedWeather> consolidated_weather { get; set; }
[DataMember]
public string time { get; set; }
[DataMember]
public string sun_rise { get; set; }
[DataMember]
public string sun_set { get; set; }
[DataMember]
public string timezone_name { get; set; }
[DataMember]
public Parent parent { get; set; }
[DataMember]
public List<Source> sources { get; set; }
[DataMember]
public string title { get; set; }
[DataMember]
public string location_type { get; set; }
[DataMember]
public int woeid { get; set; }
[DataMember]
public string latt_long { get; set; }
[DataMember]
public string timezone { get; set; }
}
MainPage.xaml
namespace _01_Weaather
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
double min;
double max;
public MainPage()
{
this.InitializeComponent();
}
private async void BtnPrikaz_OnClick(object sender, RoutedEventArgs e)
{
ConsolidatedWeather cWeather = await Vrime.ShowTemp();
min =cWeather.min_temp;
max = cWeather.max_temp;
txtTemp.Text = String.Format(min.ToString() + "\n"+ max.ToString());
}
}
Your deserializing is not on the correct object. It should be on RootObject. As the JSON retured by weather API returns data for future dates as well so if you need Min and Max temperature for today then below is the sample code.
public async Task<RootObject> ShowTemp()
{
var http = new HttpClient();
var url = String.Format("https://www.metaweather.com/api/location/44418/");
var response = await http.GetAsync(url);
var result = await response.Content.ReadAsStringAsync();
var ser = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject)ser.ReadObject(ms);
return data;
}
public async Task<ConsolidatedWeather> GetWeatherForToday()
{
RootObject ro = await ShowTemp();
ConsolidatedWeather todayWeather = ro.consolidated_weather.FirstOrDefault();
return todayWeather;
// for getting min and max
// todayWeather.min_temp;
// todayWeather.max_temp;
}
try changing the data types of the attributes min & max temperature to float and you are using wrong object type to deserialize. use your root object. Also, i'd recommend using something like restsharp for api consumption. thats going to make your life 2X easier.

Pass values of variables

I writing app for UWP
I have PCL where I writing methods for downloading json from OpenWeather
Here is code.
public class WeatherRepositoryForUWP
{
private string url = "http://api.openweathermap.org/data/2.5/weather?q=London&units=imperial&APPID=274c6def18f89eb1d9a444822d2574b5";
public async void DownloadWeather()
{
var json = await FetchAsync(url);
Debug.WriteLine(json.ToString());
}
public async Task<string> FetchAsync(string url)
{
string jsonString;
using (var httpClient = new System.Net.Http.HttpClient())
{
//var stream = httpClient.GetStreamAsync(url).Result;
var stream = await httpClient.GetStreamAsync(url);
StreamReader reader = new StreamReader(stream);
jsonString = reader.ReadToEnd();
}
return jsonString;
}
// Classes for parser
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 int temp_max { get; set; }
}
public class Wind
{
public double speed { get; set; }
public int 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; }
}
}
}
Also I have GUI where user write it city and it writing o variable when he\she taps button.
Here is code for this:
private void city_button_Click(object sender, RoutedEventArgs e)
{
string city_name;
city_name = city_text.Text;
Debug.WriteLine(city_name);
}
I need to take value from city_name and pass it to class in PCL and write to string variable.
How I can do this?
Thank's for help!
In order to be able to retrieve weather information for a custom city, you need to change your WeatherRepositoryForUWP class the following way:
public class WeatherRepositoryForUWP
{
private string urlFormat = "http://api.openweathermap.org/data/2.5/weather?q={0}&units=imperial&APPID=274c6def18f89eb1d9a444822d2574b5";
public async Task<string> DownloadWeather(string city)
{
return await FetchAsync(string.Format(urlFormat, city));
}
// Rest of class remains unchanged....
}
Then, in your click event handler, you have to do the following:
private void city_button_Click(object sender, RoutedEventArgs e)
{
string city_name;
city_name = city_text.Text;
var weatherService = new WeatherRepositoryForUWP();
string weatherData = weatherService.DownloadWeather(city_name).Result;
}

Categories