Trying to read JSON data from a JSON planetary API - c#

I am try to read data from this JSON file http://www.astro-phys.com/api/de406/states?date=1000-1-20&bodies=mars the date reads fine but I want to read :
[-168045229.22750974, 164411532.90034229, 80245103.265201837]
But as the data doesn't have a name I don't know how. This is my current code
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Windows.Forms;
namespace Planets
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
string filecontents;
string pagerequest = "http://www.astro-phys.com/api/de406/states?date=1000-1-20&bodies=mars";
WebRequest request = WebRequest.Create(#pagerequest);
WebResponse response = request.GetResponse();
Stream data = response.GetResponseStream();
string html = string.Empty;
using (StreamReader sr = new StreamReader(data))
{
filecontents = sr.ReadToEnd();
}
JavaScriptSerializer jsonSerialiser = new JavaScriptSerializer();
Results results = jsonSerialiser.Deserialize<Results>(filecontents);
richTextBox1.Text = (results.date);
Console.Write(results.date);
Console.ReadLine();
}
}
public class Results
{
public string date { get; set; }
public Position position { get; set; }
}
//public class Position
//{
// public int x { get; set; }
// public int y { get; set; }
//}
}
I am brand new to this and any help would be appreciated
Thanks

Your Results class should look something like this
public class Results
{
public string date { get; set; }
public IDictionary<string, IList<decimal[]>> results { get; set; }
public string unit { get; set; }
}
This allows for multiple planetary data points to be defined in the JSON.
i.e. if you were to call http://www.astro-phys.com/api/de406/states?date=1000-1-20&bodies=mars,earth would return mars and earth etc.
Then to access a specific co-ordinates
var coord1 = results.results["mars"][0][0]; // -168045229.22750974
var coord2 = results.results["mars"][0][1]; // 164411532.90034229
var coord3 = results.results["mars"][0][2]; // 80245103.265201837

Related

JSONException:type java.lang.String cannot be converted to JSONArray

I am trying to fetch data from 000webhost server into my xamarin.android application. connection of php mysqldatabase is working good but I am getting JSONException in one of my classes shown below.
DataPhraser.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Java.Lang;
using Org.Json;
using Object = Java.Lang.Object;
using String = System.String;
namespace database_test.database.mySQL
{
class DataPhraser : AsyncTask
{
Context c;
private Spinner sp;
private String jsonData;
JavaList<string> Universities = new JavaList<string>();
private ProgressDialog pd;
public DataPhraser(Context c, Spinner sp, string jsonData)
{
this.c = c;
this.sp = sp;
this.jsonData = jsonData;
}
protected override void OnPreExecute()
{
base.OnPreExecute();
pd = new ProgressDialog(c);
pd.SetTitle("Parse Data");
pd.SetMessage("Parsing Data..... Please Wait");
pd.Show();
}
protected override Object DoInBackground(params Object[] #params)
{
//throw new NotImplementedException();
return this.ParseData();
}
protected override void OnPostExecute(Object result)
{
base.OnPostExecute(result);
pd.Dismiss();
if (Integer.ParseInt(result.ToString()) == 0)
{
Toast.MakeText(c, "unable to Prase", ToastLength.Short).Show();
}
else
{
ArrayAdapter<string> adapter = new ArrayAdapter<string>(c, Android.Resource.Layout.SimpleListItem1, Universities);
sp.Adapter = adapter;
sp.ItemSelected += sp_ItemSelected;
}
}
private void sp_ItemSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
Toast.MakeText(c, Universities[e.Position], ToastLength.Short).Show();
}
private int ParseData()
{
try
{
JSONArray ja = new JSONArray(jsonData);
JSONObject jo = null;
Universities.Clear();
for (int i = 0; i < ja.Length(); i++)
{
jo = ja.GetJSONObject(i);
String name = jo.GetString("Country");
Universities.Add(name);
}
return 1;
}
catch (System.Exception e)
{
Console.WriteLine(e);
}
return 0;
}
}
}
I am getting error at " JSONArray ja = new JSONArray(jsonData)" this point of the code.
Mysqldatabase is
According to your gson, you can try to use Newtonsoft.Json Nuget ,for example:
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Welcome
{
[JsonProperty("Options")]
public Option[] Options { get; set; }
}
public partial class Option
{
[JsonProperty("ID")]
public long Id { get; set; }
[JsonProperty("University Name")]
public string UniversityName { get; set; }
[JsonProperty("Country")]
public string Country { get; set; }
[JsonProperty("Course")]
public string Course { get; set; }
[JsonProperty("Field of Study")]
public string FieldOfStudy { get; set; }
[JsonProperty("Course Language")]
public string CourseLanguage { get; set; }
[JsonProperty("Type of Institution")]
public string TypeOfInstitution { get; set; }
}
public partial class Welcome
{
public static Welcome FromJson(string json) => JsonConvert.DeserializeObject<Welcome>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this Welcome self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles =
DateTimeStyles.AssumeUniversal }
},
};
}
}
For more details, you can check: https://app.quicktype.io/#l=cs&r=json2csharp
Note: you can just copy your json string to the left part of above link, then it will convert the json into relative data models.

Deserialize JSON into SQLite Database

My model is GasStation.
using Newtonsoft.Json;
using SQLite;
using System;
using System.Collections.Generic;
using System.Text;
namespace TDEv2.Models
{
public class GasStation
{
[JsonProperty("costcentre")][PrimaryKey]
public string CostCentre { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
}
}
My GasStationQuery contains this:
namespace TDEv2.Models
{
public class GasStationQuery
{
public GasStation[] GasStations { get; set; }
}
}
My JSON Array looks like this:
gasstations: [
{
"id": 01,
"name": "GasStation1",
"costcentre": 123
},
{
"id": 02,
"name": "GasStation2",
"costcentre": 456
}
]
Now I want to deserialize this into my SQLite database:
using SQLite;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using TDEv2.Models;
namespace TDEv2.Data
{
public class GasStationDatabase
{
readonly SQLiteAsyncConnection database;
public GasStationDatabase(string dbPath)
{
database = new SQLiteAsyncConnection(dbPath);
database.CreateTableAsync<GasStation>().Wait();
}
public Task<List<GasStation>> GetItemsAsync()
{
return database.Table<GasStation>().ToListAsync();
}
public Task<GasStation> GetItemAsync(string costCentre)
{
return database.Table<GasStation>().Where(i => i.CostCentre == costCentre).FirstOrDefaultAsync();
}
public Task<int> SaveItemAsync(GasStation gasStation)
{
if (gasStation.CostCentre != null)
{
return database.UpdateAsync(gasStation);
}
else
{
return database.InsertAsync(gasStation);
}
}
}
}
Now I want to do an initial sync to fill my database to work with offline on the devices, but I don't know further steps since I am programming for not that long.
Here's my try to fill the database:
using System.Net;
using TDEv2.Data;
using TDEv2.Models;
namespace TDEv2.Services
{
public class InitialAsyncGasStationDatabase
{
private GasStationDatabase db;
public GasStationQuery InitialAsyncGasStationsToDatabase()
{
string json;
using (WebClient client = new WebClient())
{
json = client.DownloadString($"http://xxx/gasstations.json");
}
foreach (GasStation gasStation in json)
{
db.SaveItemAsync(gasStation);
}
return;
}
}
}
The code doesn't work. I am getting an error in the foreach section with Cannot convert type "char" to "TDEv2.Models.GasStation"
you need to deserialize your json into an object before you can save it to the db
using (WebClient client = new WebClient())
{
json = client.DownloadString($"http://xxx/gasstations.json");
}
// using newtonsoft json.net - use http://json2csharp.com/ to verfiy
// that your C# model class actually matches your json
var data = JsonConvert.DeserializeObject<GasStationQuery>(json);
foreach (GasStation gasStation in data.GasStations)
{
db.SaveItemAsync(gasStation);
}
Probably your source has a list of GasStations, so you can Deserialize your json object into a List of GasStation,
private GasStationDatabase db;
public GasStationQuery InitialAsyncGasStationsToDatabase()
{
string json;
using (WebClient client = new WebClient())
{
json = client.DownloadString($"http://xxx/gasstations.json");
}
var gasStationList = JsonConvert.DeserializeObject<List<GasStation>>(json);
foreach (GasStation gasStation in gasStationList )
{
db.SaveItemAsync(gasStation);
}
return;
}

Adding a class instance property from a list to a combobox item in C# WFA

I have a database of teas in a file, I make a new instance of the Tea class with properties like Name, Price, Flavor etc for each tea in the database from the file and place each one of the Tea type objects in a List<Tea>.
Now I need to transfer the names of the teas in a ComboBox and I can't figure it out, with a foreach probably, am I right? But how? Please help! I am probably doing something wrong with the class, see my class code (it's in Czech, don't freak out):
class Caj
{
public static string Nazev
{
get;
set;
}
public static string ZemePuvodu
{
get;
set;
}
public static string Detail
{
get;
set;
}
public static string BarvaNalevu
{
get;
set;
}
public static string Chut
{
get;
set;
}
public static int Cena
{
get;
set;
}
public static int DobaLouhovani
{
get;
set;
}
public static int PocetLzicek
{
get;
set;
}
public static string Nalevy
{
get;
set;
}
public static int TeplotaVody
{
get;
set;
}
public Caj(string nazev, string zemePuvodu, string detail, string barvaNalevu, string chut, int cena, int dobaLouhovani, int pocetLzicek, string nalevy, int teplotaVody)
{
Nazev = nazev;
ZemePuvodu = zemePuvodu;
Detail = detail;
BarvaNalevu = barvaNalevu;
Chut = chut;
Cena = cena;
DobaLouhovani = dobaLouhovani;
PocetLzicek = pocetLzicek;
Nalevy = nalevy;
TeplotaVody = teplotaVody;
}
}
And this is my Form code for now:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Zika_projekt
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static string cesta = "databaze.txt";
static int pocetCaju = File.ReadAllLines(cesta).Length;
private static List<Caj> databaze = new List<Caj>();
private void Form1_Load(object sender, EventArgs e)
{
if (File.Exists(cesta))
{
FileStream fs = new FileStream(cesta, FileMode.OpenOrCreate);
StreamReader sr = new StreamReader(fs, Encoding.UTF8);
cbNazevCaje.Items.Clear();
for (int i = 0; i < pocetCaju; i++)
{
for (int j = 1; j < i;)
{
sr.ReadLine();
}
string[] caj = sr.ReadLine().Split(';');
Caj novyCaj = new Caj(caj[0], caj[1], caj[2], caj[3], caj[4], Convert.ToInt32(caj[5]), Convert.ToInt32(caj[6]), Convert.ToInt32(caj[7]), caj[8], Convert.ToInt32(caj[9]));
cbNazevCaje.Items.Add(novyCaj.);
databaze.Add(novyCaj);
}
sr.Close();
fs.Close();
}
}
}
}
You can use DataSource property of the combobox:
cbNazevCaje.DataSource = databaze;
cbNazevCaje.DisplayMember = "Nazev"; // I'm guessing Nazev is Czech for Name?

Error filling an object array from JSON data using DataContractJsonSerializer

I have one problem. I want to read JSON data from my local link and put it in an object class. My problem is that the object[] did not fill with data. Here is my code:
This is the serverdata.cs file with my object inside that I want to fill:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace Διαχείριση
{
class serverdata
{
public προμηθευτέςRow[] Rows;
[DataContract(Name = "ΠρομηθευτέςResult")]
public struct προμηθευτέςRow
{
[DataMember(Name = "Κωδικός")]
public int Κωδικός { get; set; }
[DataMember(Name = "Όνομα")]
public string Όνομα { get; set; }
[DataMember(Name = "Επίθετο")]
public string Επίθετο { get; set; }
[DataMember(Name = "Τηλέφωνο")]
public string Τηλέφωνο { get; set; }
[DataMember(Name = "Διεύθυνση")]
public string Διεύθυνση { get; set; }
[DataMember(Name = "Mail")]
public string Mail { get; set; }
[DataMember(Name = "Προϊόντα")]
public string[] Προϊόντα { get; set; }
}
}
}
Then I have the Form.cs that I want to read the JSON data from my local server:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.Serialization.Json;
namespace Διαχείριση
{
public partial class Administator_Form : Form
{
serverdata ServerData;
public Administator_Form()
{
ServerData = new serverdata();
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
WebRequest request = WebRequest.Create(string.Format("mylocallink"));
WebResponse response = request.GetResponse();
Stream stream = request.GetResponse().GetResponseStream();
StreamReader sread = new StreamReader(stream);
//string sLine = sread.ReadLine();
//MessageBox.Show(sLine);
DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(List<serverdata.προμηθευτέςRow>));
var result = (List<serverdata.προμηθευτέςRow>)json.ReadObject(stream);
ServerData.Rows = result.ToArray();
}
}
}
Now if I call for example MessageBox.Show(ServerData.Rows[0].Κωδικός.ToString()); I get an exception:
"An unhandled exception of type 'System.IndexOutOfRangeException' occurred in Project.exe
Additional information: Index was outside the bounds of the array."
So my problem is that result didn't fill ServerData.Rows.
Here is the JSON data:
{
"ΠρομηθευτέςResult": [
{
"Mail": "mail1",
"Όνομα": "name1",
"Διεύθυνση": "address1",
"Επ‌​ίθετο": "epitheto1",
"Κωδικός": 1,
"Προϊόντα": [
"subproduct1.1",
"subproduct1.2"
],
"Τηλέ‌​φωνο": "1111111111"
},
{
"Mail": "mail2",
"Όνομα": "name2",
"Διεύθυνση": "address2",
"Επίθε‌​το": "epitheto2",
"Κωδικός": 2,
"Προϊόντα": [
"subproduct2.1",
"subproduct2.2"
],
"Τηλέφων‌​ο": "2222222222"
}
]
}
The issue is that you are trying to deserialize into a list, but in your JSON the row data is not at the root level--it is inside an object. To fix, you need to deserialize to your serverdata class directly. But first, you will need to make a couple of changes to the attributes:
Mark your serverdata class with [DataContract]
Mark the Rows property inside serverdata with [DataMember(Name = "ΠρομηθευτέςResult")]
Mark the προμηθευτέςRow struct with [DataContract]
Your class should look like this:
[DataContract]
class serverdata
{
[DataMember(Name = "ΠρομηθευτέςResult")]
public προμηθευτέςRow[] Rows { get; set; }
[DataContract]
public struct προμηθευτέςRow
{
[DataMember(Name = "Κωδικός")]
public int Κωδικός { get; set; }
[DataMember(Name = "Όνομα")]
public string Όνομα { get; set; }
[DataMember(Name = "Επίθετο")]
public string Επίθετο { get; set; }
[DataMember(Name = "Τηλέφωνο")]
public string Τηλέφωνο { get; set; }
[DataMember(Name = "Διεύθυνση")]
public string Διεύθυνση { get; set; }
[DataMember(Name = "Mail")]
public string Mail { get; set; }
[DataMember(Name = "Προϊόντα")]
public string[] Προϊόντα { get; set; }
}
}
Then, change your code to deserialize to your serverdata class:
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(serverdata));
ServerData = (serverdata)ser.ReadObject(stream);
You can remove this line as it is no longer needed:
ServerData.Rows = result.ToArray();
After these changes you should find that the Rows array is filled correctly.

ServiceStack with Protobuf format

I am trying to use protobuf format in ServiceStack Webservices ( following the example at ServiceStack: REST with ProtoBuf by Steven Hollidge. I have added a Winform application to consume the webservice. The codes are given below.
HelloService.cs
using System.Runtime.Serialization;
using ProtoBuf;
using ServiceStack.Demo.Rest;
using ServiceStack.ServiceHost;
using ServiceStack.ServiceInterface;
namespace ServiceStack.Demo.WebService
{
[DataContract]
public class Hello
{
[DataMember(Order = 1)]
public string Name { get; set; }
}
[DataContract]
public class HelloResponse
{
[DataMember(Order = 1)]
public string Result { get; set; }
}
public class HelloService : RestServiceBase<Hello>
{
public override object OnGet(Hello request)
{
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
}
Global.asax.cs
using System;
using System.Web;
using Funq;
using ServiceStack.Demo.Rest;
using ServiceStack.Demo.WebService;
using ServiceStack.WebHost.Endpoints;
namespace ServiceStack.Demo
{
public class AppHost : AppHostBase
{
public AppHost() : base("ServiceStack makes services easy!", typeof (AppHost).Assembly)
{
ServiceStack.Plugins.ProtoBuf.AppStart.Start();
}
public override void Configure(Container container)
{
Routes
.Add<Hello>("/hello")
.Add<Hello>("/hello/{Name}");
}
}
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
new AppHost().Init();
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ServiceStack.ServiceClient;
using ProtoBuf;
using ServiceStack.Plugins.ProtoBuf;
using System.Runtime.Serialization;
using ServiceStack.ServiceClient.Web;
namespace client
{
public partial class Form1 : Form
{
private ServiceClientBase _client;
private const string Url = "http://localhost/servicestack.demo/servicestack/hello?format=x-protobuf";
public Form1()
{
InitializeComponent();
}
private void Button1Click(object sender, EventArgs e)
{
this._client =
new ProtoBufServiceClient(Url);
var response = _client.Send<HelloResponse>(new Hello {Name = "ProtoBuf"});
label1.Text = response.Result;
}
public class Hello
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
}
}
I am getting System.InvalidOperationException: Type is not expected, and no contract can be inferred: client.Form1+Hello
What am I doing wrong? Please suggest.....
It looks like you have your Hello class and your HelloResponse class declared twice. Once in HelloService.cs and again as inner classes in Form.cs. Removing the duplicates from your Form.cs file should allow your ProtoBufServiceClient to reference the correct classes/types.
I have updated the Form1.cs to the following and now it is working fine( refer to http://upjnv.blogspot.in/
using System;
using System.Windows.Forms;
using ServiceStack.Plugins.ProtoBuf;
using System.Runtime.Serialization;
using ServiceStack.ServiceClient.Web;
namespace client
{
public partial class Form1 : Form
{
private ServiceClientBase _client;
private const string Url = "http://localhost/servicestack.demo/servicestack/";
public Form1()
{
InitializeComponent();
}
private void Button1Click(object sender, EventArgs e)
{
this._client =
new ProtoBufServiceClient(Url);
var response = _client.Send<HelloResponse>("GET","/hello",new Hello {Name = "ProtoBuf"});
label1.Text = response.Result;
}
}
[DataContract]
public class Hello
{
[DataMember(Order = 1)]
public string Name { get; set; }
}
[DataContract]
public class HelloResponse
{
[DataMember(Order = 1)]
public string Result { get; set; }
}
}
Put your POCO classes in the same namespace, that should do it.

Categories