How do I convert a Json response into a C# object? [duplicate] - c#

I'm trying to deserialize JSON into a custom object but all my properties are set to null and not sure what's going on. Does anyone see anything wrong?
JSON Example
{
"Keys": [
{
"RegistrationKey": "asdfasdfa",
"ValidationStatus": "Valid",
"ValidationDescription": null,
"Properties": [
{
"Key": "Guid",
"Value": "i0asd23165323sdfs68661358"
}
]
}
]
}
Here is my Code, where strResponseValid is the JSON above.
Keys myDeserializedObjValid = (Keys)JsonConvert.DeserializeObject(strResponseValid, typeof(Keys));
validationStatusValid = myDeserializedObjValid.ValidationStatus;
Here are my classes
public class Keys
{
public string RegistrationKey { get; set; }
public string ValidationStatus { get; set; }
public string ValidationDescription { get; set; }
public List<Properties> PropertiesList { get; set; }
}
public class Properties
{
public string Key { get; set; }
public string Value { get; set; }
}

check if the destination type has internal (or private) set modifier for those properties, even if the property has public access modifier itself.
public class Summary{
public Class2 Prop1 { get; internal set; }
public Class1 prop2 { get; set; }
}
Solution: remove those explicit internal access modifier and make them writable from outside

Your JSON has an outer object which contains a collection of Key objects. The following code works (I tested it):
class KeyWrapper
{
public List<Key> Keys { get; set; }
}
class Key
{
public string RegistrationKey { get; set; }
public string ValidationStatus { get; set; }
public string ValidationDescription { get; set; }
public List<Properties> Properties { get; set; }
}
public class Properties
{
public string Key { get; set; }
public string Value { get; set; }
}
public void DeserializeKeys()
{
const string json = #"{""Keys"":
[
{
""RegistrationKey"": ""asdfasdfa"",
""ValidationStatus"": ""Valid"",
""ValidationDescription"": null,
""Properties"": [
{
""Key"": ""Guid"",
""Value"": ""i0asd23165323sdfs68661358""
}
]
}
]
}";
var keysWrapper = Newtonsoft.Json.JsonConvert.DeserializeObject<KeyWrapper>(json);
}

The problem here is that you're defining Keys as just a class, when it's actually a property.
public class Response
{
public Keys Keys { get; set; }
}
public class Keys
{
public string RegistrationKey { get; set; }
public string ValidationStatus { get; set; }
public string ValidationDescription { get; set; }
public List<Properties> PropertiesList { get; set; }
}
public class Properties
{
public string Key { get; set; }
public string Value { get; set; }
}

JSON.NET is an opt-in serialization library. The properties in your objects require attributes in order to flag them as being included in the JSON structure.
public class Keys
{
[JsonProperty(PropertyName = "RegistrationKey")]
public string RegistrationKey { get; set; }
[JsonProperty(PropertyName = "ValidationStatus")]
public string ValidationStatus { get; set; }
[JsonProperty(PropertyName = "ValidationDescription")]
public string ValidationDescription { get; set; }
[JsonProperty(PropertyName = "Properties")]
public List<Properties> PropertiesList { get; set; }
}
public class Properties
{
[JsonProperty(PropertyName = "Key")]
public string Key { get; set; }
[JsonProperty(PropertyName = "Value")]
public string Value { get; set; }
}

You don't need to define PropertiesList as a list in the class just call the PropertiesList Class as below.
public class Keys
{
public string RegistrationKey { get; set; }
public string ValidationStatus { get; set; }
public string ValidationDescription { get; set; }
public PropertiesList PropertiesList { get; set; }
}
public class PropertiesList
{
public string Key { get; set; }
public string Value { get; set; }
}
Then try using the following to deserialize:
keys myDeserializedObjValid = JsonConvert.DeserializeObject<keys>(strResponseValid);

Related

Parse a json generated by jstree in C#

I'm currently receiving the following string of an array that was generated from JsTree:
"[
{
"id":"j1_1",
"text":"Root node 1",
"icon":true,
"li_attr":{
"id":"j1_1"
},
"a_attr":{
"href":"#",
"id":"j1_1_anchor"
},
"data":{
},
"children":[
{
"id":"j1_2",
"text":"Child 1",
"icon":true,
"li_attr":{
"id":"j1_2"
},
"a_attr":{
"href":"#",
"id":"j1_2_anchor"
},
"data":{
},
"children":[
]
}
]
}
]"
I'm trying to deserialize the following item by using
JsTreeModel aaa = Newtonsoft.Json.JsonConvert.DeserializeObject<JsTreeModel>(json);
With JsTreeModel being this class:
public class JsTreeModel
{
[JsonProperty("id")]
public string id { get; set; }
[JsonProperty("text")]
public string text { get; set; }
[JsonProperty("icon")]
public string icon { get; set; }
[JsonProperty("li_attr")]
public string li_attr { get; set; }
[JsonProperty("a_attr")]
public string a_attr { get; set; }
[JsonProperty("data")]
public string data { get; set; }
}
But I'm getting the error`:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'AccesosWeb.Entidad.JsTree.JsTreeModel' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
I think the issue is with how the class is structured, but I don't know how to build it.
This is the model you need in consideration of the json you paste:
You can use the main object:
JsTreeModel myDeserializedClass = JsonConvert.DeserializeObject<JsTreeModel>(json);
and the object is:
public class JsTreeModel
{
public List<MyArray> MyArray { get; set; }
}
public class LiAttr
{
public string id { get; set; }
}
public class AAttr
{
public string href { get; set; }
public string id { get; set; }
}
public class Data
{
}
public class Child
{
public string id { get; set; }
public string text { get; set; }
public bool icon { get; set; }
public LiAttr li_attr { get; set; }
public AAttr a_attr { get; set; }
public Data data { get; set; }
public List<object> children { get; set; }
}
public class MyArray
{
public string id { get; set; }
public string text { get; set; }
public bool icon { get; set; }
public LiAttr li_attr { get; set; }
public AAttr a_attr { get; set; }
public Data data { get; set; }
public List<Child> children { get; set; }
}

JSON DeserializeObject to Model without Key Name

I currently have JSON coming in as follows:
{"36879":[{"min_qty":1,"discount_type":"%","csp_price":10}],"57950":[{"min_qty":1,"discount_type":"flat","csp_price":650}]}
This contains a list of the following records
ProductId
MinQty
DiscountType
Price
I need to deserialize this into the following model:
public class CustomerSpecificPricing
{
string productId { get; set; }
public virtual List<CustomerSpecificPricingDetail> CustomerSpecificPricingDetails { get; set; }
}
public class CustomerSpecificPricingDetail
{
public string min_qty { get; set; }
public string discount_type { get; set; }
public string csp_price { get; set; }
}
The problem is that the "productId" of each record is missing the key name.
If I run my JSON through J2C, I get the following:
public class 36879 {
public int min_qty { get; set; }
public string discount_type { get; set; }
public int csp_price { get; set; }
}
public class 57950 {
public int min_qty { get; set; }
public string discount_type { get; set; }
public int csp_price { get; set; }
}
public class Root {
public List<_36879> _36879 { get; set; }
public List<_57950> _57950 { get; set; }
}
Which is obviously incorrect.
How would I deserialize my object correctly?
You would need to deserialize it into a dictionary first and then map it into the format you require after. Something like this should work:
var dict = JsonConvert.DeserializeObject<Dictionary<string, IEnumerable<CustomerSpecificPricingDetail>>>();
var result = dict.Select(kvp => new CustomerSpecificPricing { ProductId = Int32.Parse(kvp.Key), CustomerSpecificPricingDetails = kvp.Value });
Id also recommend you follow the conventional standards of naming. In this case properties in classes should be PascalCase,
e.g. your classes now become:
public class CustomerSpecificPricing
{
[JsonProperty("productId ")]
public string ProductId { get; set; }
public virtual List<CustomerSpecificPricingDetail> CustomerSpecificPricingDetails { get; set; }
}
and
public class CustomerSpecificPricingDetail
{
[JsonProperty("min_qty")]
public string MinQty { get; set; }
[JsonProperty("discount_type ")]
public string DiscountType { get; set; }
[JsonProperty("csp_price ")]
public string CspPrice { get; set; }
}

Invalid type when generate the json?

I've this json:
{
"page": "36",
"bookmaker_urls": {
"13": [{
"link": "http://www.bet365.com/home/?affiliate=365_179024",
"name": "Bet 365"
}]
},
"block_service_id": "competition_summary_block_competitionmatchessummary",
"round_id": "36003",
"outgroup": "",
"view": "1",
"competition_id": "13"
}
I've inserted this on this tool: http://json2csharp.com/
this will return:
public class __invalid_type__13
{
public string link { get; set; }
public string name { get; set; }
}
public class BookmakerUrls
{
public List<__invalid_type__13> __invalid_name__13 { get; set; }
}
public class RootObject
{
public int page { get; set; }
public BookmakerUrls bookmaker_urls { get; set; }
public string block_service_id { get; set; }
public int round_id { get; set; }
public bool outgroup { get; set; }
public int view { get; set; }
public int competition_id { get; set; }
}
why there is an invalid type?
13 is not a valid property name in .NET, and the tool you're using seems to try to map each JSON property to .NET Class property.
What you probably want is bookmaker_urls to be a dictionary:
public class BookmakerUrl
{
public string link { get; set; }
public string name { get; set; }
}
public class RootObject
{
public int page { get; set; }
public Dictionary<string, List<BookmakerUrl>> bookmaker_urls { get; set; }
public string block_service_id { get; set; }
public int round_id { get; set; }
public bool outgroup { get; set; }
public int view { get; set; }
public int competition_id { get; set; }
}
The generator generates the name of properties and types from the name of properties in the Json.
There is a property "13" in the Json. A name starting with a digit would not be a valid name in c#.
So, the generator just adds the prefix "invalid_name" or "invalid_type" to the generated names. This does not mean that there was any problem or that you cannot use the generated code.

Deserializing this JSON response to C#

I have this specific JSON response that I am trying to deserialize without success. I am hoping someone can help me.
Here is the JSON response I get:
{
"num_locations": 1,
"locations": {
"98765": {
"street1": "123 Fake Street",
"street2": "",
"city": "Lawrence",
"state": "Kansas",
"postal_code": "66044",
"s_status": "20",
"system_state": "Off"
}
}
}
I used json2csharp http://json2csharp.com and got these recommended classes:
public class __invalid_type__98765
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
public class Locations
{
public __invalid_type__98765 __invalid_name__98765 { get; set; }
}
public class RootObject
{
public int num_locations { get; set; }
public Locations locations { get; set; }
}
But when I try to use it in my code:
var locationResponse = JsonConvert.DeserializeObject<RootObject>(response.Content);
What I get is (Watch):
locationResponse : {RestSharpConsoleApplication.Program.RootObject} : RestSharpConsoleApplication.Program.RootObject
locations : {RestSharpConsoleApplication.Program.Locations} : RestSharpConsoleApplication.Program.Locations
__invalid_name__98765 : null : RestSharpConsoleApplication.Program.__invalid_type__98765
num_locations : 1 : int
Obviously I am not creating (json2csharp) the right classes for the DeserializeObject, and sadly I have no control over the JSON response (vendor = SimpliSafe).
It is obvious the "98765" is meant to be a value (location number) but json2csharp makes it into this __invalid_type__98765 class and this is probably why it gets null.
Any idea how should the classes look for this particular JSON to be successfully deserialized?
Thanks!
Zachs
You should be able to do this with a dictionary:
public class MyData{
[JsonProperty("locations")]
public Dictionary<string, Location> Locations {get;set;}
}
public class Location
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
Do you have a non-Express version of Visual Studio? If so, copy the JSON to clipboard and then go to the Visual Studio menu: Edit >> Paste special >> Paste JSON as classes.
Using that gives:
public class Rootobject {
public int num_locations { get; set; }
public Locations locations { get; set; }
}
public class Locations {
public _98765 _98765 { get; set; }
}
public class _98765 {
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
That suggests your JSON structure is not quite right.
You can also specify the property name via an attribute to use to get around this:
public class RootObject
{
public int num_locations { get; set; }
public Locations locations { get; set; }
}
public class Locations
{
[JsonProperty("98765")]
public LocationInner Inner { get; set; }
}
public class LocationInner
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
...but it would really be better if the JSON were properly formatted such that the Locations was actually an array of location objects.

Generate C# object from Json string and parse Json string to generated object

I am trying to generate C# class using the JSON string from here http://json2csharp.com/ this works fine. But I can't parse the JSON to the object generated by the website.
Here is the JSON string
{
"searchParameters":{
"key":"**********",
"system":"urn:oid:.8"
},
"message":" found one Person matching your search criteria.",
"_links":{
"self":{
"href":"https://integration.rest.api.test.com/v1/person?key=123456&system=12.4.34.."
}
},
"_embedded":{
"person":[
{
"details":{
"address":[
{
"line":["5554519 testdr"],
"city":"testland",
"state":"TT",
"zip":"12345",
"period":{
"start":"2003-10-22T00:00:00Z",
"end":"9999-12-31T23:59:59Z"
}
}
],
"name":[
{
"use":"usual",
"family":["BC"],
"given":["TWO"],
"period":{
"start":"9999-10-22T00:00:00Z",
"end":"9999-12-31T23:59:59Z"
}
}
],
"gender":{
"code":"M",
"display":"Male"
},
"birthDate":"9999-02-03T00:00:00Z",
"identifier":[
{
"use":"unspecified",
"system":"urn:oid:2.19.8",
"key":"",
"period":{
"start":"9999-10-22T00:00:00Z",
"end":"9999-12-31T23:59:59Z"
}
}
],
"telecom":[
{
"system":"email",
"value":"test#test.com",
"use":"unspecified",
"period":{
"start":"9999-10-22T00:00:00Z",
"end":"9999-12-31T23:59:59Z"
}
}
],
"photo":[
{
"content":{
"contentType":"image/jpeg",
"language":"",
"data":"",
"size":0,
"hash":"",
"title":"My Picture"
}
}
]
},
"enrolled":true,
"enrollmentSummary":{
"dateEnrolled":"9999-02-07T21:39:11.174Z",
"enroller":"test Support"
},
"_links":{
"self":{
"href":"https://integration.rest.api.test.com/v1/person/-182d-4296-90cc"
},
"unenroll":{
"href":"https://integration.rest.api.test.com/v1/person/1b018dc4-182d-4296-90cc-/unenroll"
},
"personLink":{
"href":"https://integration.rest.api.test.com/v1/person/-182d-4296-90cc-953c/personLink"
},
"personMatch":{
"href":"https://integration.rest.api.commonwellalliance.org/v1/person/-182d-4296-90cc-/personMatch?orgId="
}
}
}
]
}
}
Here is the code I use to convert to the object.
JavaScriptSerializer js = new JavaScriptSerializer();
var xx = (PersonsearchVM)js.Deserialize(jsonstr, typeof(PersonsearchVM));
Is there any other wat to generate the object and parse?
I think you have some invalid characters in your JSON string. Run it through a validator and add the necessary escape characters.
http://jsonlint.com/
You aren't casting it to the right object. Cast it to the type RootObject.
Eg
JavaScriptSerializer js = new JavaScriptSerializer();
var xx = (RootObject)js.Deserialize(jsonstr, typeof(RootObject));
The code that json 2 csharp creates is this:
public class SearchParameters
{
public string key { get; set; }
public string system { get; set; }
}
public class Self
{
public string href { get; set; }
}
public class LinKs
{
public Self self { get; set; }
}
public class Period
{
public string start { get; set; }
public string end { get; set; }
}
public class Address
{
public List<string> line { get; set; }
public string city { get; set; }
public string __invalid_name__state { get; set; }
public string zip { get; set; }
public Period period { get; set; }
}
public class PerioD2
{
public string start { get; set; }
public string end { get; set; }
}
public class Name
{
public string use { get; set; }
public List<string> family { get; set; }
public List<string> given { get; set; }
public PerioD2 __invalid_name__perio
d { get; set; }
}
public class Gender
{
public string __invalid_name__co
de { get; set; }
public string display { get; set; }
}
public class Period3
{
public string start { get; set; }
public string __invalid_name__end { get; set; }
}
public class Identifier
{
public string use
{ get; set; }
public string system { get; set; }
public string key { get; set; }
public Period3 period { get; set; }
}
public class Period4
{
public string start { get; set; }
public string end { get; set; }
}
public class Telecom
{
public string system { get; set; }
public string value { get; set; }
public string use { get; set; }
public Period4 period { get; set; }
}
public class Content
{
public string contentType { get; set; }
public string language { get; set; }
public string __invalid_name__dat
a { get; set; }
public int size { get; set; }
public string hash { get; set; }
public string title { get; set; }
}
public class Photo
{
public Content content { get; set; }
}
public class Details
{
public List<Address> address { get; set; }
public List<Name> name { get; set; }
public Gender gender { get; set; }
public string birthDate { get; set; }
public List<Identifier> identifier { get; set; }
public List<Telecom> telecom { get; set; }
public List<Photo> photo { get; set; }
}
public class EnrollmentSummary
{
public string dateEnrolled { get; set; }
public string __invalid_name__en
roller { get; set; }
}
public class Self2
{
public string href { get; set; }
}
public class UnEnroll
{
public string href { get; set; }
}
public class PersonLink
{
public string href { get; set; }
}
public class PersonMatch
{
public string href { get; set; }
}
public class Links2
{
public Self2 self { get; set; }
public UnEnroll __invalid_name__un
enroll { get; set; }
public PersonLink personLink { get; set; }
public PersonMatch personMatch { get; set; }
}
public class Person
{
public Details details { get; set; }
public bool __invalid_name__e
nrolled { get; set; }
public EnrollmentSummary enrollmentSummary { get; set; }
public Links2 _links { get; set; }
}
public class Embedded
{
public List<Person> person { get; set; }
}
public class RootObject
{
public SearchParameters searchParameters { get; set; }
public string message { get; set; }
public LinKs __invalid_name___lin
ks { get; set; }
public Embedded _embedded { get; set; }
}
The following function will convert JSON into a C# class where T is the class type.
public static T Deserialise<T>(string json)
{
T obj = Activator.CreateInstance<T>();
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(ms); //
return obj;
}
}
You need a reference to the System.Runtime.Serialization.json namespace.
The function is called in the following manner;
calendarList = Deserialise<GoogleCalendarList>(calendarListString);
calendarlist being the C# class and calendarListString the string containing the JSON.

Categories