I'm a little stumped on this one. Everything I do to check this out says it is a valid Json array, but JsonConvert.Deserialize says it is an object. Can someone point out what I'm doing wrong?
Code to replicate:
var data = "[{\"User\": {\"Identifier\": \"24233\",\"DisplayName\": \"Commerce Test Student\",\"EmailAddress\": \"email#email.ca\",\"OrgDefinedId\": \"UniqueId1\",\"ProfileBadgeUrl\": null,\"ProfileIdentifier\": \"zzz123\"},\"Role\": {\"Id\": 153,\"Code\": null,\"Name\": \"Commerce Student\"}}]";
var items = JsonConvert.DeserializeObject<List<T>>(data);
Where T is an object that matches the format below:
public class OrgUnitUser
{
public User User { get; set; }
public RoleInfo Role { get; set; }
}
public class User
{
public string Identifier { get; set; }
public string DisplayName { get; set; }
public string EmailAddress { get; set; }
public string OrgDefinedId { get; set; }
public string ProfileBadgeUrl { get; set; }
public string ProfileIdentifier { get; set; }
}
public class RoleInfo
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
It results in an error
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[CoverPages.Models.D2L.OrgUnitUser]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
Any/all help is appreciated!
var data = "[{\"User\": {\"Identifier\": \"24233\",\"DisplayName\": \"Commerce Test Student\",\"EmailAddress\": \"email#email.ca\",\"OrgDefinedId\": \"UniqueId1\",\"ProfileBadgeUrl\": null,\"ProfileIdentifier\": \"zzz123\"},\"Role\": {\"Id\": 153,\"Code\": null,\"Name\": \"Commerce Student\"}}]";
public class User
{
public string Identifier { get; set; }
public string DisplayName { get; set; }
public string EmailAddress { get; set; }
public string OrgDefinedId { get; set; }
public object ProfileBadgeUrl { get; set; }
public string ProfileIdentifier { get; set; }
}
public class Role
{
public int Id { get; set; }
public object Code { get; set; }
public string Name { get; set; }
}
public class RootObject
{
public User User { get; set; }
public Role Role { get; set; }
}
var items = JsonConvert.DeserializeObject<List<RootObject>>(data);
or
var items = JsonConvert.DeserializeObject<List<RootObject>>(data)[0];
Try this code I thinks he working good
result:
Thanks to Taras for the confirmation, but there is nothing wrong with the code itself.
When using a generic in JsonConver.Deserialize, it gives the error I listed above, however putting in the actual type of OrgUnitUser into the list, rather than T results in the convert succeeding.
Changing the code from
var items = JsonConvert.DeserializeObject<List<T>>(data);
to
var items = JsonConvert.DeserializeObject<List<OrgUnitUser>>(data);
Fixed the issue
Related
I have a code REST API response which is json, and parsing to JObject and pulling a value from it. But i am getting the error when parsing to JObject.
Error: "Unexpected character encountered while parsing value: S. Path '', line 0, position 0."
Is there any other way to convert Json string to C# object.
I have the following code:
using Newtonsoft.Json;
using (HttpResponseMessage message = httpclient.GetAsync(folderIdURL).Result)
{
if(message.IsSuccessStatusCode)
{
var dataobjects = message.Content.ReadAsStringAsync();
//dataobjects = "{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/","title":"DQL query results","author":[{"name":"EMC Documentum"}],"updated":"2019-05-02T15:19:52.508+00:00","page":1,"items-per-page":100,"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)"}],"entries":[{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)&index=0","title":"0b0111738011c114","updated":"2019-05-02T15:19:52.508+00:00","published":"2019-05-02T15:19:52.508+00:00","links":[{"rel":"edit","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c114"}],"content":{"json-root":"query-result","definition":"https://gbc-dev5.cloud.wc.com/DctmRest/repositori es/dmgbsap_crt/types/dm_sysobject","properties":{"r_object_id":"0b0111738011c114","object_name":"04"},"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c114"}]}},{"id":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/?dql=SELECT%20r_object_id%2cobject_name%20FROM%20dm_sysobject%20WHERE%20FOLDER%20(%27%2fgbc%2fUS%2fOSA-ATTACHMENT%2f2019%27)&index=1","title":"0b0111738011c115","updated":"2019-05-02T15:19:52.509+00:00","published":"2019-05-02T15:19:52.509+00:00","links":[{"rel":"edit","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c115"}],"content":{"json-root":"query-result","definition":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/types/dm_sysobject","properties":{"r_object_id":"0b0111738011c115","object_name":"05"},"links":[{"rel":"self","href":"https://gbc-dev5.cloud.wc.com/DctmRest/repositories/dmgbsap_crt/objects/0b0111738011c115"}]}}]}"
JObject responseObj = JObject.Parse(dataobjects.ToString());
String id = (String)responseObj["entries" -->"content"-->"properties"-->"object_name"];
}
}
}
I am expecting the value from (String)responseObject["enteries"]["content"][" properties"]["object_name"]
JObjects are a pain. You could get a sample of the JSON response and paste it into a converter like json2csharp.com. It will generate a class for you which you can then use like so:
Generated Class:
public class MyClass
{
public string SomeProperty { get; set; }
public string AnotherProperty { get; set; }
}
Usage:
if (message.IsSuccessStatusCode)
{
var deserializedObject = JsonConvert.DeserializeObject<MyClass>(response.Content.ReadAsStringAsync().Result);
Console.WriteLine(deserializedObject.SomeProperty);
}
I would suggest to follow those steps:
You need to check that your json is actually a json, because an error says it is not. You can use online tools like this
If possible, avoid JObject and generate real classes. It is not that hard if you know the structure, and you can use another online tools
Modify your code to use classes
so you will have something like:
using System;
using Newtonsoft.Json;
namespace ConsoleApp11
{
class Program
{
public class Message
{
public Enteries enteries { get; set; }
}
public class Enteries
{
public Content content { get; set; }
}
public class Content
{
public Properties properties { get; set; }
}
public class Properties
{
public string object_name { get; set; }
}
static void Main(string[] args)
{
var input = "{\"enteries\":{\"content\":{ \"properties\":{ \"object_name\":\"your value string\"}}}}";
Message msg = JsonConvert.DeserializeObject<Message>(input);
Console.WriteLine(msg?.enteries?.content?.properties?.object_name ?? "no value");
Console.ReadKey();
}
}
}
I hope it helps 😊
Thank you so much for all the help and trips. Finally i am able to get the required value from JSON string.
Here is the Final code json2csharp.com
public class Author
{
public string name { get; set; }
}
public class Link
{
public string rel { get; set; }
public string href { get; set; }
}
public class Link2
{
public string rel { get; set; }
public string href { get; set; }
}
public class Properties
{
public string r_object_id { get; set; }
public string object_name { get; set; }
}
public class Link3
{
public string rel { get; set; }
public string href { get; set; }
}
public class Content
{
public string json_root { get; set; }
public string definition { get; set; }
public Properties properties { get; set; }
public List<Link3> links { get; set; }
}
public class Entry
{
public string id { get; set; }
public string title { get; set; }
public DateTime updated { get; set; }
public DateTime published { get; set; }
public List<Link2> links { get; set; }
public Content content { get; set; }
}
public class RootObject
{
public string id { get; set; }
public string title { get; set; }
public List<Author> author { get; set; }
public DateTime updated { get; set; }
public int page { get; set; }
public int items_per_page { get; set; }
public List<Link> links { get; set; }
public List<Entry> entries { get; set; }
}
Using Newtonsoft.Json
First get the list of entries from the responseObj. Then loop each entries and use LINQ to JSON to get values by property name or index.
You can use Item[Object] index on JObject/JArray and then cast the returned JValue to the type you want
JObject responseObj = JObject.Parse(dataobjects.ToString());
// get JSON result objects into a list
IList<JToken> entries = responseObj ["entries"].Children().ToList();
foreach(JToken entry in entries)
{
string object_name = (string) entry["content"]["properties"]["object_name"];
}
I'm having problems deserializing the data I'm getting from Shodan. Below are the classes I got from json2csharp and I'm trying to create an array of the matches and loop through them. It seems like I have tried with everything except a working array by now. The data itself is matches as root with objects of them that contain location (with its own data etc). An except below that I cut out a bit.
This is my error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'Shodan.Match[]' because the type requ
ires a JSON array (e.g. [1,2,3]) to deserialize correctly.
var data = JsonConvert.DeserializeObject<Match[]>(allData);
{"matches": [{"product": "product", "hash": 0, "ip": 123123, "isp": "Verizon Internet Services"}], "total": 1}
public class Location
{
public string city { get; set; }
public string region_code { get; set; }
public object area_code { get; set; }
public double longitude { get; set; }
public string country_code3 { get; set; }
public double latitude { get; set; }
public string postal_code { get; set; }
public object dma_code { get; set; }
public string country_code { get; set; }
public string country_name { get; set; }
}
public class Options
{
}
public class Shodan
{
public string crawler { get; set; }
public string id { get; set; }
public string module { get; set; }
public Options options { get; set; }
}
public class Match
{
public int hash { get; set; }
public int ip { get; set; }
public string isp { get; set; }
public string transport { get; set; }
public string data { get; set; }
public string asn { get; set; }
public int port { get; set; }
public List<string> hostnames { get; set; }
public Location location { get; set; }
public DateTime timestamp { get; set; }
public List<string> domains { get; set; }
public string org { get; set; }
public object os { get; set; }
public Shodan _shodan { get; set; }
public string ip_str { get; set; }
public string product { get; set; }
}
public class RootObject
{
public List<Match> matches { get; set; }
public int total { get; set; }
}
You could create another class like
var allData =
{"matches": [{"product": "product", "hash": 0, "ip": 123123, "isp": "Verizon Internet Services"}], "total": 1}
public class MyMatches {
public Match[] matches {get; set;}
}
and then use that in the deserializer.
var data = JsonConvert.DeserializeObject<MyMatches>(allData);
This is if the JSON code sample you gave us is correct.
CORRECTION
Just saw the RootObject class.
Just use that.
I am trying to consume a REST API via a C# Console Application and I've got as far as getting the webservice to return the JSON file, with the format:
{"status":200,"result":{"postcode":"SW1W0DT","quality":1,"eastings":528813,"northings":178953,"country":"England","nhs_ha":"London","longitude":-0.145828,"latitude":51.494853,"european_electoral_region":"London","primary_care_trust":"Westminster","region":"London","lsoa":"Westminster 023E","msoa":"Westminster 023","incode":"0DT","outcode":"SW1W","parliamentary_constituency":"Cities of London and Westminster","admin_district":"Westminster","parish":"Westminster, unparished area","admin_county":null,"admin_ward":"Warwick","ccg":"NHS Central London (Westminster)","nuts":"Westminster","codes":{"admin_district":"E09000033","admin_county":"E99999999","admin_ward":"E05000647","parish":"E43000236","parliamentary_constituency":"E14000639","ccg":"E38000031","nuts":"UKI32"}}}
I have created a class AddressInfo which is as follows:
public class AddressInfo {
public string postcode { get; set; }
public int quality { get; set; }
public int eastings { get; set; }
public int northings { get; set; }
public string country { get; set; }
public string nhs_ha { get; set; }
public string admin_county { get; set; }
public string admin_district { get; set; }
public string admin_ward { get; set; }
public double longitude { get; set; }
public double latitude { get; set; }
public string parliamentary_constituency { get; set; }
public string european_electoral_region { get; set; }
public string primary_care_trust { get; set; }
public string region { get; set; }
public string parish { get; set; }
public string lsoa { get; set; }
public string msoa { get; set; }
public string ccg { get; set; }
public string nuts { get; set; }
public object codes { get; set; }
}
The code to call the API and get the values is:
string strJSON = string.Empty;
strJSON = rClient.makeRequest();
Console.Write(strJSON);
AddressInfo AI = new AddressInfo();
AI = Newtonsoft.Json.JsonConvert.DeserializeObject<AddressInfo>(strJSON);
However, when I debug, AI is returning the values as "NULL".
Thanks
Notice that your JSON has a nested structure. The AddressInfo is contained within its result property, it isn't at the top level.
Your actual class structure to deserialize the entire JSON response should look something like this (I've called the class JsonResponse but you can name it whatever you want):
class JsonResponse{
public int status { get; set; }
public AddressInfo result { get; set; }
}
Then deserialize it like this:
JsonResponse res = JsonConvert.DeserializeObject<JsonResponse>(strJSON);
AddressInfo addressInfo = res.result;
You're missing the fact that you need an outer class that has the properties int status and AdressInfo result.
You don't need to create a separate class to deserialize the entire response, this can be done dynamically to achieve desired result:
var source = "(your JSON");
dynamic data = JObject.Parse(source);
var d = JsonConvert.SerializeObject(data.result);
AddressInfo account = JsonConvert.DeserializeObject<AddressInfo>(d);
Your JSON is nested. The result is a nested object. That's why you are experiencing this issue.
I am getting the below JSON in response from a REST API.
{
"data":{
"id":123,
"zoneid":"mydomain.com",
"parent_id":null,
"name":"jaz",
"content":"172.1 6.15.235",
"ttl":60,
"priority":null,
"type":"A",
"regions":[
"global"
],
"system_record":false,
"created_at":"2017-09-28T12:12:17Z",
"updated_at":"2017-09-28T12:12:17Z"
}
}
and trying to resolve using below code but that doesn't result in a correctly deserialized type.
var model = JsonConvert.DeserializeObject<ResponseModel>(response);
below is a class according the field I received in JSON response.
public class ResponseModel
{
public int id { get; set; }
public string zone_id { get; set; }
public int parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public int priority { get; set; }
public string type { get; set; }
public string[] regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
What is missing?
You're missing a wrapper class.
public class Wrapper
{
public ResponseModel data {get;set}
}
and then do:
var model = JsonConvert.DeserializeObject<Wrapper>(response).data;
to get the instance of your ResponseModel out the data property.
You can deduct this from your json:
{ "data":
{ "id":123, /*rest omitted */ }
}
The type that will receive this JSON needs to have a property named data. The suggested Wrapper class acts as that type.
According to json2csharp website, your model seems to be incorrect. Try this one :
public class ResponseModel
{
public int id { get; set; }
public string zoneid { get; set; }
public object parent_id { get; set; }
public string name { get; set; }
public string content { get; set; }
public int ttl { get; set; }
public object priority { get; set; }
public string type { get; set; }
public List<string> regions { get; set; }
public bool system_record { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
}
public class RootObject
{
public ResponseModel data { get; set; }
}
Here a cool trick you can do in Visual Studio 2015-2017 where it generates the the correct class if you just copy the JSON (ctrl + c).
You need to create a new class in visual studio and once inside the class go to Edit menu -> Paste special -> paste JSON As Classes.
Steps to generate json class
This will generate the C# object for that json for you and save you all the hassle :)
Your model does not match your response - it matches the data property. Simply wrap another object round it
public class ResponseData
{
public ResponseModel Data {get; set; {
}
and then
var model = JsonConvert.DeserializeObject<ResponseData>(response);
I have read some articles but didnt fix my problem , i have a problem with JSON string when deserialize, here the string
{"table":"sy_version","effected":2,"data":[{"mod_id":"CS","sub_mod":"sbm_sl.exe","version":"2015.11.07.1","upload_date ":"2015-11-10 11:34:13"},{"mod_id":"FA","sub_mod":"sbm_fa.exe","version":"2015.11.09","upload_date ":"2015-11-10 11:34:13"}]}
And this is my class
public class Datum
{
public string mod_id { get; set; }
public string sub_mod { get; set; }
public string version { get; set; }
public DateTime upload_date { get; set; }
}
public class sy_periode
{
public string table { get; set; }
public int effected { get; set; }
public IList<Datum> datas { get; set; }
}
public static void test(string str) {
// dynamic sy_periode = JsonConvert.DeserializeObject(str);
var sy_periode = JsonConvert.DeserializeObject<sy_periode>(str);
foreach (var data in sy_periode.datas)
{
Console.WriteLine(data.sub_mod);
}
}
When I executed, string table and effected have value, but datas is null, this is the error message
Object reference not set to an instance of an object.
It shouldn't be datas, it should have the same name as JSON object: data.
Here is the correct classes structure:
public class Datum
{
public string mod_id { get; set; }
public string sub_mod { get; set; }
public string version { get; set; }
public DateTime upload_date { get; set; }
}
public class sy_periode
{
public string table { get; set; }
public int effected { get; set; }
public IList<Datum> data { get; set; }
}
Also, note that in JSON your upload_date properties have an odd whitespace in the end: upload_date. It may be a typo. However, if it is an actual input and since C# member name cannot contain spaces, you can try to specify the name in order to serialize it:
[JsonProperty(PropertyName = "upload_date ")]
public DateTime upload_date { get; set; }
I am not quite sure that it will work, but I see no reasons of why it shouldn't.