Trying to get JSON data from ThingSpeak however getting the above error,
works well with JSON placeholder as the URL.
Here is my main cs code:
namespace Drip
{
public class Feed
{
public DateTime Created_at { get; set; }
public int Entry_id { get; set; }
public string Field1 { get; set; }
}
public partial class DripPage : TabbedPage
{
private const string Url = "https://thingspeak.com/channels/301726/field/1.json";
private HttpClient _client = new HttpClient();
private ObservableCollection<Feed> _data;
public DripPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
var content = await _client.GetStringAsync(Url);
var data = JsonConvert.DeserializeObject<List<Feed>>(content);
_data = new ObservableCollection<Feed>(data);
postsListView.ItemsSource = _data;
base.OnAppearing();
}
Here is my JSON:
{
"channel": {
"id": 301726,
"name": "Testing ESP8266",
"description": "Water meter pulse count",
"latitude": "0.0",
"longitude": "0.0",
"field1": "Water Pulse",
"created_at": "2017-07-12T12:19:38Z",
"updated_at": "2017-09-26T08:41:17Z",
"elevation": "54",
"last_entry_id": 151
},
"feeds": [
{
"created_at": "2017-08-15T13:14:28Z",
"entry_id": 52,
"field1": "13.00\r\n\r\n"
},
{
"created_at": "2017-08-15T13:14:44Z",
"entry_id": 53,
"field1": "13.00\r\n\r\n"
},
{
"created_at": "2017-08-15T13:14:59Z",
"entry_id": 54,
"field1": "13.00\r\n\r\n"
}
]
}
The returned json is not an array, so it can't be deserialized as a List<Feed>, hence an exception is thrown. It is an object, and one of that object's members is the array that you are interested in. The backing C# class to deserialize should have the following members:
public class RootObject
{
public Channel channel { get; set; }
public List<Feed> feeds { get; set; }
}
public class Channel
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public string latitude { get; set; }
public string longitude { get; set; }
public string field1 { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
public string elevation { get; set; }
public int last_entry_id { get; set; }
}
public class Feed
{
public DateTime created_at { get; set; }
public int entry_id { get; set; }
public string field1 { get; set; }
}
Instead of deserializing to a List<Feed>, you would deserialize to a RootObject (or whatever you choose to call it):
var data = JsonConvert.DeserializeObject<RootObject>(content);
_data = new ObservableCollection<Feed>(data.feeds);
try this maybe it will work fine for you
first: place this code on your activity and instanciate all var;you will create a javalist to deserialize your json, then you will the method webclient to get your json, then you will use the method runonuithread to excute the process in background.
articles = new JavaList<RootObject>();
mWebClient = new WebClient();
mUrl = new Uri(urlAddress);
mWebClient.DownloadDataAsync("https://thingspeak.com/channels/301726/field/1.json");
mWebClient.DownloadDataCompleted += MWebClient_DownloadDataCompleted;
second: the method mWebClient.DownloadDataCompleted will generate this :
private void MWebClient_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
RunOnUiThread(() =>
{
try
{
string json = Encoding.UTF8.GetString(e.Result);
articles = JsonConvert.DeserializeObject<JavaList<RootObject>>(json);
mAdapter = new ArticleAdapterCostum(this, articles);
mListView.Adapter = mAdapter;
}
catch (Exception exception)
{
Toast.MakeText(this, " Vueillez verifier votre connexion a internet puis reessayer ", ToastLength.Short).Show();
}
});
}
don't forget to create a costum adapter to your listview.
Related
How can i deserialize a local json file to an object?
I'm trying to deserialize a local json file in xamarin but it just doesn't work i read many guides and watched some tutorials but none of them helped and most of them give the same code i'm using right now
My code:
public test()
{
InitializeComponent();
List<Rootobject> ob = new List<Rootobject>();
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(test)).Assembly;
Stream stream = assembly.GetManifestResourceStream($"TunisiaPrayer.states.json");
string text = "";
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
ob = JsonConvert.DeserializeObject<List<Rootobject>>(text);
//printing the json file to make sure it read it fully
//i get no error here
DisplayJson.Text = text;
//try catch to test if it was deserialized or not
try
{
//printing a property of ob in a label element to see if it works
DisplayData.Text = ob[2].Property1.data.gouvernorat.intituleAn;
}
catch (Exception ex)
{
DisplayData.Text = ex.Message;
}
}
RootObject Class:
namespace TunisiaPrayer.Models
{
public class Rootobject
{
public Class1 Property1 { get; set; }
}
public class Class1
{
public Data data { get; set; }
}
public class Data
{
public Gouvernorat gouvernorat { get; set; }
public Delegation[] delegation { get; set; }
}
public class Gouvernorat
{
public int id { get; set; }
public string intituleAr { get; set; }
public string intituleAn { get; set; }
}
public class Delegation
{
public int id { get; set; }
public string intituleAr { get; set; }
public string intituleAn { get; set; }
}
}
sample of states.json:
[{
"data": {
"gouvernorat": {
"id": 358,
"intituleAr": "اريانة",
"intituleAn": "Ariana"
},
"delegation": [{
"id": 631,
"intituleAr": "اريانة",
"intituleAn": "Ariana"
},
{
"id": 534,
"intituleAr": "التظامن",
"intituleAn": "Attadhamon"
},
{
"id": 532,
"intituleAr": "سكرة",
"intituleAn": "Soukra"
}
]
}
},
{
"data": {
"gouvernorat": {
"id": 362,
"intituleAr": "القصرين",
"intituleAn": "Kasserine"
},
"delegation": [{
"id": 579,
"intituleAr": "العيون",
"intituleAn": "El Ayoun"
},
{
"id": 576,
"intituleAr": "سبيبة",
"intituleAn": "Sbiba"
},
{
"id": 575,
"intituleAr": "سبيطلة",
"intituleAn": "Sbitla"
},
{
"id": 573,
"intituleAr": "تالة",
"intituleAn": "Tala"
}
]
}
}]
error: Object reference not set to an instance of an object
note that when i print ob.Count it gives me the correct length of the list but i can't access any data in it
you have to use Root[] , not just root, try this
var obj =JsonConvert.DeserializeObject< List<Root>>(text);
test
var displayData = obj[1].data.gouvernorat.intituleAn; // = Kasserine
classes
public class Root
{
public Data data { get; set; }
}
public class Data
{
public Gouvernorat gouvernorat { get; set; }
public List<Delegation> delegation { get; set; }
}
public class Gouvernorat
{
public int id { get; set; }
public string intituleAr { get; set; }
public string intituleAn { get; set; }
}
public class Delegation
{
public int id { get; set; }
public string intituleAr { get; set; }
public string intituleAn { get; set; }
}
I have built a service that is retrieving a sample file.
return await _httpClient.GetFromJsonAsync<BitcoinDetails>("https://localhost:44356/sample-data/jsonresult.json");
Example
"id": 1,
"name": "Bitcoin",
"symbol": "BTC",
"slug": "bitcoin",
"num_market_pairs": 9550,
"date_added": "2013-04-28T00:00:00.000Z",
"tags": [
"mineable",
"pow",
"sha-256",
"store-of-value",
"state-channels"
],
"max_supply": 21000000, -- or null if not set
"circulating_supply": 18555956,
"total_supply": 18555956,
"platform": null,
"cmc_rank": 1,
"last_updated": "2020-11-27T21:22:02.000Z",
"quote": {
"USD": {
"price": 17069.598651577406,
"volume_24h": 38571181876.87967,
"percent_change_1h": 1.46329039,
"percent_change_24h": 0.92405679,
"percent_change_7d": -8.25816318,
"market_cap": 316742721516.32965,
"last_updated": "2020-11-27T21:22:02.000Z"
}
}
}
Now I have a class that has the following properties
public class Datum
{
public int id { get; set; }
public string name { get; set; }
public string symbol { get; set; }
public string slug { get; set; }
public int num_market_pairs { get; set; }
public DateTime date_added { get; set; }
public List<string> tags { get; set; }
public long? max_supply { get; set; }
public double circulating_supply { get; set; }
public double total_supply { get; set; }
public Platform platform { get; set; }
public int cmc_rank { get; set; }
public DateTime last_updated { get; set; }
public Quote quote { get; set; }
}
Keeping in mind that there are many more records I am getting the following error
Unhandled exception rendering component: The JSON value could not be converted to System.Nullable`1[System.Int64]. Path: $.data[80].max_supply |
make dto nullable and then try as follows:
var response = client.GetAsync(apiUrl);
if (response.Result.IsSuccessStatusCode)
{
var data = response.Result.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<Datum>(data.Result);
return result;
}
I ended up using a proxy call however this code did work:
var response = await _httpClient.GetAsync("https://localhost:5001/proxy");
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<BitcoinDetails>(data);
return result;
}
else
{
throw new Exception("Failed to get data");
}
and added this to the class property
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
I started to learn C# and some Json, I am trying to get this form of Json format:
Desired Output :
I have tried this:
static void Main(string[] args)
{
var myjason = new myJson
{
ContentDisposition = "",
md5 = "da855ff838250f45d528a5a05692f14e",
file_name = "MyFile.docx",
features = new[] { "te" },
te = new te { reports = new[] { "pdf", "xml" } },
// images = new img { { a.id = "7e6fe36e-889e-4c25-8704-56378f0830df", a.revision = 1 }, { a.id = "e50e99f3-5963-4573-af9e-e3f4750b55e2", a.revision = 1 } }
};
string json = JsonConvert.SerializeObject(myjason, Formatting.Indented);
Console.WriteLine(json);
}
public class myJson
{
public string ContentDisposition{ get; set; }
public string md5 { get; set; }
public string file_name { get; set; }
public string[] features { get; set; }
public te te { get; set; }
public img images { get; set; }
}
public class a
{
public string id { get; set; }
public int revision { get; set; }
}
public class te
{
public string[] reports { get; set; }
}
public class img
{
public a[] images { get; set; }
}
And here is my current output:
Current output:
Please help, thanks a lot!
I think you are a bit confused about what's going on here. It looks like you're trying to POST some JSON to some endpoint.
Content-Disposition and Content-Type are HTTP headers. They are not JSON.
The JSON starts with the first { and this is the body of the POST. To create that body, you could use a C# object like:
public class MyJson {
public class MyRequest request {get ;set;}
}
public class MyRequest {
public string md5 {get;set;}
public string file_name {get;set;}
public string file_type {get;set;}
public List<string> features {get;set;}
public MyTe te {get;set;}
}
public class MyTe {
public List<string> reports {get;set;}
public List<MyImages> images {get;set;}
}
public class MyImages {
public string id {get;set;}
public int revision {get;set;}
}
And then use JsonConvert.SerializeObject on a MyJson object. To set the HTTP headers depends on what you're trying to do and with which tools, and that probably belongs in a different question.
EDIT: I said "and so on" because it's really just a rote exercise, and there are better tools to do this but I've updated.
Content-Disposition and Content-Type are request headers so they don't need to be in your json body
Here I've also demostrated how you can set a custom json property name using JsonProperty attribute.
static void Main(string[] args)
{
var myjason = new myJsonClass
{
Request = new requestClass
{
md5 = "da855ff838250f45d528a5a05692f14e",
file_name = "MyFile.docx",
file_type = "docx",
features = new[] { "te" },
te = new te
{
reports = new[] { "pdf", "xml" },
images = new a[] { new a { id = "7e6fe36e-889e-4c25-8704-56378f0830df", revision = 1 }, new a { id = "e50e99f3-5963-4573-af9e-e3f4750b55e2", revision = 1 } }
},
}
};
string json = JsonConvert.SerializeObject(myjason, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(json);
}
public class myJsonClass
{
[JsonProperty("request")]
public requestClass Request { get; set; }
}
public class requestClass
{
public string md5 { get; set; }
public string file_name { get; set; }
public string file_type { get; set; }
public string[] features { get; set; }
public te te { get; set; }
}
public class a
{
public string id { get; set; }
public int revision { get; set; }
}
public class te
{
public string[] reports { get; set; }
public a[] images { get; set; }
}
Output:
{
"request": {
"md5": "da855ff838250f45d528a5a05692f14e",
"file_name": "MyFile.docx",
"file_type": "docx",
"features": [
"te"
],
"te": {
"reports": [
"pdf",
"xml"
],
"images": [
{
"id": "7e6fe36e-889e-4c25-8704-56378f0830df",
"revision": 1
},
{
"id": "e50e99f3-5963-4573-af9e-e3f4750b55e2",
"revision": 1
}
]
}
}
}
We have to do some changes in existing JSON response and it requires to modify existing c# code too. Till now I've tried but don't get the exact idea about the formatting as it is new for me.
Can any one please check and suggest the changes in below code?
Existing JSON message:
"hotel_room_types": {
"QUEEN": {
"code": "QUEEN",
"bed_type": {
"standard": [
5
],
"custom": []
},
"extra_bed_type": {
"standard": [
5
],
"custom": []
},
"accessibility": "compliant_with_local_laws_for_disabled",
"room_smoking_policy": "non_smoking"
}
}
In above JSON message we have to replace the "bed_type" and "extra_bed_type" with "bed_configurations" and "extra_bed_configurations" in below newly provided format by client:
"hotel_room_types": {
"QUEEN": {
"code": "QUEEN",
"bed_configurations": [
[{
"type": "standard",
"code": 3,
"count": 1
}],
[{
"type": "standard",
"code": 1,
"count": 2
}]
],
"extra_bed_configurations": [
[{
"type": "standard",
"code": 900302,
"count": 1
},
{
"type": "custom",
"name": "Rollaway with wheel locks and adjustable height",
"count": 1
}]
],
"accessibility": "compliant_with_local_laws_for_disabled",
"room_smoking_policy": "non_smoking"
}
}
Existing C# code to generate the JSON response message format:
public class HotelRoomType
{
public string code { get; set; }
public string name { get; set; }
public string description { get; set; }
public List<Photo> photos { get; set; }
public Amenities room_amenities { get; set; }
public string room_size { get; set; }
public string room_size_units { get; set; }
public BedType bed_type { get; set; }
public BedType extra_bed_type { get; set; }
public RoomViewType room_view_type { get; set; }
public string accessibility { get; set; }
public MaxOccupancy max_occupancy { get; set; }
public string room_smoking_policy { get; set; }
}
Below is the code to fill the data in required fields of JSON message its inside a method which contains lines of code so I get it separately:
HotelRoomType hotelrmtype = new HotelRoomType();
hotelrmtype.bed_type = Common.GetStandardBedTypeMappingID(rm.BedType);
if (rm.NumOfBed > 1)
hotelrmtype.extra_bed_type = hotelrmtype.bed_type; //same as bed type
hotelrmtypeDict.Add(rm.Code, hotelrmtype); //Binding Data into Dictionary.
GetStandardBedTypeMappingID() contains :
public static CRS.TripConnect.BedType GetStandardBedTypeMappingID(short code)
{
CRS.TripConnect.BedType tripConnectBedType = new CRS.TripConnect.BedType();
List<int> standardBedTypes = new List<int>();
List<object> customBedTypes = new List<object>();
tripConnectBedType.standard = standardBedTypes;
tripConnectBedType.custom = customBedTypes; //These is blank.
short id = 0;
switch (code)
{
case 10:
id = 3;
break;
case 20: // 20 Queen Q 5
id = 5;
break;
case 30: // 30 Double D 1
id = 1;
break;
case 40: // 40 Twin T 8
id = 8;
break;
}
standardBedTypes.Add(id);
return tripConnectBedType;
}
Update: With the help of #Sam Answer below I have modified the code:
public class HotelRoomType
{
//Added following properties
public List<List<Bed_Configurations>> bed_configurations { get; set; }
public List<List<Extra_Bed_Configurations>> extra_bed_configurations { get; set; }
}
Created two new classes as:
public class Bed_Configurations
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
}
public class Extra_Bed_Configurations
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
public string name { get; set; }
}
Now the question is: How to fill these two list?
I'm trying to achieve this like below but it is giving me conversion error.
Bed_Configurations bdConfig = new Bed_Configurations();
bdConfig.type = "Standard";
bdConfig.code = Common.GetStandardBedTypeMappingIDnew(rm.BedType);
bdConfig.count = rm.NumOfBed;
hotelrmtype.bed_configurations.Add(bdConfig);
Error Message:
Please Advise the changes in the above code so as to get the required JSON message. Appreciate your help!
public class RootClass
{
public HotelRoomType hotel_room_types { get; set; }
}
public class HotelRoomType
{
public BedModelAndDetails QUEEN { get;set; }
}
public class BedModelAndDetails
{
public string accessibility { get; set; }
public string room_smoking_policy { get; set; }
public string code { get; set; }
//public BedType bed_type { get; set; }
public object bed_type { get; set; }
//public BedType extra_bed_type { get; set; }
public object extra_bed_type { get; set; }
public List<List<BedConfiguration>> bed_configurations { get; set; }
public List<List<BedConfiguration>> extra_bed_configurations { get; set; }
}
public class BedType
{
public List<int> standard { get; set; }
public List<int> custom { get; set; }
}
public class BedConfiguration
{
public string type { get; set; }
public int code { get; set; }
public int count { get; set; }
}
[TestMethod]
public void ReplaceJson()
{
var inputJson1 = "{\"hotel_room_types\": {\"QUEEN\": {\"code\": \"QUEEN\", \"bed_type\": {\"standard\": [5],\"custom\": [] }, \"extra_bed_type\": { \"standard\": [5], \"custom\": [] },\"accessibility\": \"compliant_with_local_laws_for_disabled\", \"room_smoking_policy\": \"non_smoking\" } " +"}}";
var input1 = JsonConvert.DeserializeObject<RootClass>(inputJson1, new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore});
var inputJson2 = "{\"hotel_room_types\": {\"QUEEN\": {\"code\": \"QUEEN\",\"bed_configurations\": [[{\"type\": \"standard\",\"code\": 3,\"count\": 1}],[{\"type\": \"standard\",\"code\": 1,\"count\": 2}]],\"extra_bed_configurations\": [[{\"type\": \"standard\",\"code\": 900302,\"count\": 1},{\"type\": \"custom\",\"name\": \"Rollaway with wheel locks and adjustable height\",\"count\": 1}]],\"accessibility\": \"compliant_with_local_laws_for_disabled\",\"room_smoking_policy\": \"non_smoking\"} }}";
var input2 = JsonConvert.DeserializeObject<RootClass>(inputJson2);
//var finalInput = new RootClass();
//finalInput.hotel_room_types = inputJson1
//input1.hotel_room_types.QUEEN.bed_configurations = input2.hotel_room_types.QUEEN.bed_configurations;
//input1.hotel_room_types.QUEEN.extra_bed_configurations = input2.hotel_room_types.QUEEN.extra_bed_configurations;
input1.hotel_room_types.QUEEN.bed_type = input2.hotel_room_types.QUEEN.bed_configurations;
input1.hotel_room_types.QUEEN.extra_bed_type = input2.hotel_room_types.QUEEN.extra_bed_configurations;
}
Does this help?
This question already has answers here:
How can I parse a JSON string that would cause illegal C# identifiers?
(3 answers)
Closed 8 years ago.
I am attempting to parse JSON from a web service using Json.NET, the web service returns data in the following format:
{
"0": {
"ID": 193,
"Title": "Title 193",
"Description": "Description 193",
"Order": 5,
"Hyperlink": "http://someurl.com"
},
"1": {
"ID": 228,
"Title": "Title 228",
"Description": "Description 228",
"Order": 4,
"Hyperlink": "http://someurl.com"
},
"2": {
"ID": 234,
"Title": "Title 234",
"Description": "Description 234",
"Order": 3,
"Hyperlink": "http://someurl.com"
}
}
I used json2sharp to generate a class from the JSON:
public class __invalid_type__0
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class __invalid_type__1
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class __invalid_type__2
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class RootObject
{
public __invalid_type__0 __invalid_name__0 { get; set; }
public __invalid_type__1 __invalid_name__1 { get; set; }
public __invalid_type__2 __invalid_name__2 { get; set; }
}
I then cleaned up the class and was left with the following:
public class Articles
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public string Hyperlink { get; set; }
}
public class FeaturedArticles
{
public List<Articles> articles { get; set; }
}
When I attempt to load the data into my singleton for use in the app:
private void fetchFeaturedArticles()
{
var client = new RestClient (_featuredArticlesJsonUrl);
var request = new RestRequest (Method.GET);
var response = client.Execute (request);
_featuredArticles = JsonConvert.DeserializeObject<FeaturedArticles> (response.Content);
foreach (Articles a in _featuredArticles.Articles)
Console.WriteLine (a.Title);
}
I find that the Articles do not get deserialized.
I've verified that the JSON data is returned from the web service. I believe the issue exists in the structure of my JSON feed, where each item returned from the feed is given a name which equals the index the item is being returned as.
I am new to using Json.NET so I'm not sure how I should proceed; I cannot change the structure of the JSON feed but need to consume it's data. Anyone have any recommendations?
You don't need FeaturedArticles class, you can deserialize the JSON into a Dictionary<string, Articles> like this:
private void fetchFeaturedArticles()
{
var client = new RestClient (_featuredArticlesJsonUrl);
var request = new RestRequest (Method.GET);
var response = client.Execute (request);
Dictionary<string, Articles> _featuredArticles = JsonConvert.DeserializeObject<Dictionary<string, Articles>>(response.Content);
foreach (string key in _featuredArticles.Keys)
{
Console.WriteLine(_featuredArticles[key].Title);
}
}
Demo: https://dotnetfiddle.net/ZE1BMl