I am sending data in a post request as follow:
{
"HospitalId": "Hospital-0232",
"DataSliceTimestamp": "2020.08.10",
"HourQuarter": "00:01",
"Data": [
{"country":"US","state":"MS","county":"bolivar","lat":32.354668,"lng":-89.398528,"type":"ICU","measure":"1000HAB","beds":0.241539,"population":33121,"year":2014,"source":"khn","source_url":"https://khn.org/news/as-coronavirus-spreads-widely-millions-of-older-americans-live-in-counties-with-no-icu-beds/"},
{"country":"US","state":"MS","county":"bolivar","lat":32.354668,"lng":-89.398528,"type":"ICU","measure":"1000HAB","beds":0.241539,"population":33121,"year":2015,"source":"khn","source_url":"https://khn.org/news/as-coronavirus-spreads-widely-millions-of-older-americans-live-in-counties-with-no-icu-beds/"},
{"country":"US","state":"MS","county":"bolivar","lat":32.354668,"lng":-89.398528,"type":"ICU","measure":"1000HAB","beds":0.241539,"population":33121,"year":2016,"source":"khn","source_url":"https://khn.org/news/as-coronavirus-spreads-widely-millions-of-older-americans-live-in-counties-with-no-icu-beds/"},
{"country":"US","state":"MS","county":"bolivar","lat":32.354668,"lng":-89.398528,"type":"ICU","measure":"1000HAB","beds":0.241539,"population":33121,"year":2017,"source":"khn","source_url":"https://khn.org/news/as-coronavirus-spreads-widely-millions-of-older-americans-live-in-counties-with-no-icu-beds/"},
{"country":"US","state":"MS","county":"bolivar","lat":32.354668,"lng":-89.398528,"type":"ICU","measure":"1000HAB","beds":0.241539,"population":33121,"year":2018,"source":"khn","source_url":"https://khn.org/news/as-coronavirus-spreads-widely-millions-of-older-americans-live-in-counties-with-no-icu-beds/"}
]
}
And for reading the body I am doing it like this:
public class RequestBody
{
public string HospitalId { get; set; }
public string DataSliceTimestamp { get; set; }
public string HourQuarter { get; set; }
public string[] Data { get; set; }
}
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
RequestBody data = JsonConvert.DeserializeObject<RequestBody>(requestBody);
But I get error:
Newtonsoft.Json: Unexpected character encountered while parsing value: [. Path 'Data', line 5, position 13.
Something is wrong while reading array data, please guide.
You need to strongly type your JSON input to an object array not a string.
Here's an example of what the object could look like:
public class Datum
{
[JsonProperty("country")]
public string country { get; set; }
[JsonProperty("state")]
public string state { get; set; }
[JsonProperty("county")]
public string county { get; set; }
[JsonProperty("lat")]
public double lat { get; set; }
[JsonProperty("lng")]
public double lng { get; set; }
[JsonProperty("type")]
public string type { get; set; }
[JsonProperty("measure")]
public string measure { get; set; }
[JsonProperty("beds")]
public double beds { get; set; }
[JsonProperty("population")]
public int population { get; set; }
[JsonProperty("year")]
public int year { get; set; }
[JsonProperty("source")]
public string source { get; set; }
[JsonProperty("source_url")]
public string source_url { get; set; }
}
public class RequestBody
{
[JsonProperty("HospitalId")]
public string HospitalId { get; set; }
[JsonProperty("DataSliceTimestamp")]
public string DataSliceTimestamp { get; set; }
[JsonProperty("HourQuarter")]
public string HourQuarter { get; set; }
[JsonProperty("Data")]
public IList<Datum> Data { get; set; }
}
You can then deserialize it like you're already doing:
RequestBody data = JsonConvert.DeserializeObject<RequestBody>(requestBody);
I solved this by using dynamic type and by pulling out data field from the request body.
// Reading body
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
// Parse through the request body string and make it in appropriate format.
dynamic RequestBody_data = JsonConvert.DeserializeObject(requestBody);
var Data = RequestBody_data["Data"].ToString();
Through this I was able to get the data field string and then I can split it with "}," to get all the rows. Thanks
So basically I ran the JSON through jsonUtils which created an object, which turned out to be several objects.
So 2 questions please:
How to best populate objects from URL?
Can I select which objects to populate, i.e. I don't want to do all 20 objects?
In advance, thank you!!
WebClient client = new WebClient();
string myJSON = client.DownloadString("https://someURL.geojson");
var myClass = Newtonsoft.Json.JsonConvert.DeserializeObject(myJSON);
Console.Write(myClass.ToString());
public class PrecipType
{
public string units { get; set; }
public string value { get; set; }
}
public class Press
{
public string units { get; set; }
public string value { get; set; }
}
public class Atmo
{
public AirTemperature air_temp{ get; set; }
public Dewpoint dew_point{ get; set; }
public Wind { get; set; }
public Pressure pressure { get; set; }
}
public class ObsTime
{
public string units { get; set; }
public string value { get; set; }
}
I am trying to deserialize this link , but I keep getting this error.
Error reading string. Unexpected token: StartObject. Path 'responseData'.
From what i have googled, the problem seems to be the setup of my object I'm trying to deserialize into. Below is my class:
public class FeedSearchResult
{
[JsonProperty("responseData")]
public String ResponseData { get; set; }
[JsonProperty("query")]
public String Query { get; set; }
[JsonProperty("entries")]
public string[] Entries { get; set; }
[JsonProperty("responseDetails")]
public object ResponseDetails { get; set; }
[JsonProperty("responseStatus")]
public String ResponseStatsu { get; set; }
}
public class ResultItem
{
[JsonProperty("title")]
public String Title { get; set; }
[JsonProperty("url")]
public String Url { get; set; }
[JsonProperty("link")]
public String Link { get; set; }
}
What am I doing wrong in my class? Any help would be greatly appreciated.
Your data model only has two levels of nesting, but the JSON returned has three. If you look at the formatted JSON using https://jsonformatter.curiousconcept.com/ you will see:
{
"responseData":{
"query":"Official Google Blogs",
"entries":[
{
"url":"https://googleblog.blogspot.com/feeds/posts/default",
"title":"\u003cb\u003eOfficial Google Blog\u003c/b\u003e",
"contentSnippet":"\u003cb\u003eOfficial\u003c/b\u003e weblog, with news of new products, events and glimpses of life inside \u003cbr\u003e\n\u003cb\u003eGoogle\u003c/b\u003e.",
"link":"https://googleblog.blogspot.com/"
},
In particular your data model has responseData as a String when it needs to be a contained object. This is the specific cause of the exception.
If you upload the JSON to http://json2csharp.com/ you will get the following data model, which can be used to deserialize this JSON:
public class ResultItem
{
public string url { get; set; }
public string title { get; set; }
public string contentSnippet { get; set; }
public string link { get; set; }
}
public class ResponseData
{
public string query { get; set; }
public List<ResultItem> entries { get; set; }
}
public class RootObject
{
public ResponseData responseData { get; set; }
//Omitted since type is unclear.
//public object responseDetails { get; set; }
public int responseStatus { get; set; }
}
I'm using the ACE code editor to gather Json and send it to my application. Once the Json hits the application, I need to make sure there are certain key's inside the json so I am using JsonConvert.DeserisalizeObject<t> to do this. Here's how:
public void SubmitReport(string JsonStringSend)
{
try
{
ReportItem RptItem = JsonConvert.DeserializeObject<ReportItem>(JsonStringSend);
}
catch(err)
{
return View(err);
}
}
and:
public class ReportItem
{
public Guid ReportID;
public bool RequiresFilter;
public string MimeType { get; set; }
public string ExternalID { get; set; }
public DateTime CreatedBy { get; set; }
public string ExecutionScript { get; set; }
public string ExecutionParameter { get; set; }
public string ExecutionOrderBy { get; set; }
public List<DynamicFilter> DynamicFilters { get; set; }
public bool RequiresOrgID { get; set; }
public QueryFilter ReportFilter { get; set; }
public QueryRule ReportRules { get; set; }
public List<QueryColumn> Columns { get; set; }
}
But for some reason, it bounces right over the catch even when I make sure some of the key's are incorrect. Am I not understanding the correct usage JsonConvert.DeserisalizeObject<t>? Or, is there a better way to be doing this check?
By default, the deserializer "tries it's best" to deserialize the object. But JSon.NET supports validation, the "straightforward" way is probably JSon Schema: http://www.newtonsoft.com/jsonschema.
Simple case can be handled with JSon.NET directly:
public class ReportItem
{
[JsonProperty(Required = Required.Always)]
public bool RequiresFilter;
[JsonProperty(Required = Required.Always)]
public string MimeType { get; set; }
public DateTime CreatedBy { get; set; }
public string ExecutionScript { get; set; }
public string ExecutionParameter { get; set; }
public string ExecutionOrderBy { get; set; }
public bool RequiresOrgID { get; set; }
}
The first JSON is look like this
The second JSON is look like this
How can I deserialize them? I have been follow this example but it's not working.
Here's my code.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var w = new WebClient();
Observable
.FromEvent<DownloadStringCompletedEventArgs>(w, "DownloadStringCompleted")
.Subscribe(r =>
{
var deserialized =
JsonConvert.DeserializeObject<List<Place>>(r.EventArgs.Result);
PlaceList.ItemsSource = deserialized;
});
w.DownloadStringAsync(
new Uri("http://mobiilivantaa.lightscreenmedia.com/api/place"));
//For 2nd JSON
//w.DownloadStringAsync(
//new Uri("http://mobiilivantaa.lightscreenmedia.com/api/place/243"));
}
These are classes for 1st JSON.
public class Place
{
public string id { get; set; }
public string title { get; set; }
public string latitude { get; set; }
public string longitude { get; set; }
public string www { get; set; }
}
public class RootObjectJSON1
{
public List<Place> Places { get; set; }
}
These are classes for JSON2
public class Address
{
public string street { get; set; }
public string postal_code { get; set; }
public string post_office { get; set; }
}
public class Image
{
public string id { get; set; }
public string filename { get; set; }
public string path { get; set; }
}
public class RootObjectJSON2
{
public string id { get; set; }
public string title { get; set; }
public string description { get; set; }
public string latitude { get; set; }
public string longitude { get; set; }
public string www { get; set; }
public string phone { get; set; }
public string email { get; set; }
public string contact_person { get; set; }
public Address address { get; set; }
public List<Image> images { get; set; }
}
it looks that you should be deserializing object RootObjectJSON1 or RootObjectJSON2, e.g.:
var deserialized = JsonConvert.DeserializeObject<RootObjectJSON1>(r.EventArgs.Result);
Also it seems that collection Places should be with lowercase p at beginning or you need to tell Json.NET that this property should be deserialized with different name, e.g.:
[JsonProperty(PropertyName="places")]
public List<Place> Places { get; set; }
Generally I tend to use arrays for deserialization (from my experience works better) so I'll suggest to rewrite it to this:
public class RootObjectJSON1
{
public Place[] places { get; set; }
}
There is very good tool named json2csharp available at http://json2csharp.com/ - just put sample of JSON there and it will spit out classes in C# (doesn't detect DateTime so you might need to change that).