I am serializing a JSON that looks like this:
{ "id": 107, "group_id": 6, "default_billing": "6538", "default_shipping": "6539", "created_at": "2016-08-03 11:48:49", "updated_at": "2018-08-01 09:58:10", "created_in": "Admin", "dob": "1900-01-01", "email": "XXX@yahoo.com", "firstname": "XXX SERVICES LTD", "lastname": ".", "store_id": 1, "website_id": 1, "addresses": [ { "id": 138, "customer_id": 107, "region": { "region_code": "Default", "region": "Default", "region_id": 0 }, "region_id": 0, "country_id": "NG", "street": [ "Default" ], "telephone": "08012345678", "postcode": "23401", "city": "Default", "firstname": "XXX SERVICES LTD", "lastname": "." }, { "id": 5833, "customer_id": 107, "region": { "region_code": "Default", "region": "Default", "region_id": 0 }, "region_id": 0, "country_id": "NG", "street": [ "Default" ], "telephone": "08012345678", "postcode": "23401", "city": "Default", "firstname": "XXX SERVICES LTD", "lastname": "." }, { "id": 5834, "customer_id": 107, "region": { "region_code": "Default", "region": "Default", "region_id": 0 }, "region_id": 0, "country_id": "NG", "street": [ "Default" ], "telephone": "08012345678", "postcode": "23401", "city": "Default", "firstname": "XXX SERVICES LTD", "lastname": "." }, { "id": 6538, "customer_id": 107, "region": { "region_code": "Default", "region": "Default", "region_id": 0 }, "region_id": 0, "country_id": "NG", "street": [ "Default" ], "telephone": "08012345678", "postcode": "23401", "city": "Default", "firstname": "XXX SERVICES LTD", "lastname": ".", "default_billing": true }, { "id": 6539, "customer_id": 107, "region": { "region_code": "Default", "region": "Default", "region_id": 0 }, "region_id": 0, "country_id": "NG", "street": [ "Default" ], "telephone": "08012345678", "postcode": "23401", "city": "Default", "firstname": "XXX SERVICES LTD", "lastname": ".", "default_shipping": true } ], "disable_auto_group_change": 0, "custom_attributes": [ { "attribute_code": "is_active", "value": "1" } ] }
Here's a C# class I used in serializing, I referenced it from my xpp project:
using System.Collections.Generic; using Newtonsoft.Json; namespace JsonSerializer { public class CustomerInfo { [JsonProperty(PropertyName = "id")] public int Id { get; set; } [JsonProperty(PropertyName = "group_id")] public int GroupId { get; set; } [JsonProperty(PropertyName = "default_billing")] public string DefaultBilling { get; set; } [JsonProperty(PropertyName = "default_shipping")] public string DefaultShipping { get; set; } [JsonProperty(PropertyName = "created_at")] public string CreatedAt { get; set; } [JsonProperty(PropertyName = "updated_at")] public string UpdatedAt { get; set; } [JsonProperty(PropertyName = "created_in")] public string CreatedIn { get; set; } [JsonProperty(PropertyName = "dob")] public string Dob { get; set; } [JsonProperty(PropertyName = "email")] public string Email { get; set; } [JsonProperty(PropertyName = "firstname")] public string FirstName { get; set; } [JsonProperty(PropertyName = "lastname")] public string LastName { get; set; } [JsonProperty(PropertyName = "store_id")] public int StoreId { get; set; } } public class Address { public string Id { get; set; } [JsonProperty("country_id")] public string CountryId { get; set; } public string Telephone { get; set; } } public class Root { [JsonProperty("id")] public int Id { get; set; } [JsonProperty("group_id")] public int GroupId { get; set; } [JsonProperty("default_billing")] public string DefaultBilling { get; set; } [JsonProperty("default_shipping")] public string DefaultShipping { get; set; } [JsonProperty("created_at")] public string CreatedAt { get; set; } [JsonProperty("updated_at")] public string UpdatedAt { get; set; } [JsonProperty("created_in")] public string CreatedIn { get; set; } [JsonProperty("dob")] public string Dob { get; set; } [JsonProperty("Email")] public string email { get; set; } [JsonProperty("firstname")] public string FirstName { get; set; } [JsonProperty("lastname")] public string LastName { get; set; } [JsonProperty("store_id")] public int StoreId { get; set; } } public class ConvertToObject { public string Convert(string jsonString) { JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(); Root root = JsonConvert.DeserializeObject<Root>(jsonString, settings); return JsonConvert.SerializeObject(root, Formatting.Indented, settings); } } }
This is my Integrator.xpp file
class Integrator { public static void Main(Args _args) { Integrator::execute(); } public static void execute() { AddressContract addressContract; List customers; CustomerInfoContract customerContract; str baseUrl = "urltogetthejson.com/.../V1"; str getFullCustomers = baseUrl+"customer/getFullCustomers"; str filteredCust = getFullCustomers+"?xxxxxxxxxxxxxx"; JsonSerializer.ConvertToObject serializer; str dataList; List data, address; ListEnumerator recEnum, addressEnum, customerEnum; System.Net.WebHeaderCollection headers = new System.Net.WebHeaderCollection(); headers.Add("Authorization", "Bearer XXXXXXXXXXXXXXXXXX"); str resp = WebService::getRequest(filteredCust,headers); customers = FormJsonSerializer::deserializeCollection(classNum(List),resp, Types::Class,classStr(CustomerInfoContract)); customerEnum = customers.getEnumerator(); while (customerEnum.moveNext()) { customerContract = customerEnum.current(); info(customerContract.FirstName()); } info(strfmt("Response is : %1 ", resp)); } }
Here's my CustomerInfoContract.xpp class:
[DataContractAttribute] class CustomerInfoContract { int id, groupId, storeId; str defaultBilling, defaultShipping, createdAt, updatedAt, createdIn, dob, email, firstName, lastName; List addresses; [DataMemberAttribute("id")] public int Id(int _id = id) { id = _id; return id; } [DataMemberAttribute("group_id")] public int GroupId(int _groupId = groupId) { groupId = _groupId; return groupId; } [DataMemberAttribute("default_billing")] public str DefaultBilling(str _defaultBilling = defaultBilling) { defaultBilling = _defaultBilling; return defaultBilling; } [DataMemberAttribute("default_shipping")] public str DefaultShipping(str _defaultShipping = defaultShipping) { defaultShipping = _defaultShipping; return defaultShipping; } [DataMemberAttribute("created_at")] public str CreatedAt(str _createdAt = createdAt) { createdAt = _createdAt; return createdAt; } [DataMemberAttribute("updated_at")] public str UpdatedAt(str _updatedAt = updatedAt) { updatedAt = _updatedAt; return updatedAt; } [DataMemberAttribute("created_in")] public str CreatedIn(str _createdIn = createdIn) { createdIn = _createdIn; return createdIn; } [DataMemberAttribute("dob")] public str Dob(str _dob = dob) { dob = _dob; return dob; } [DataMemberAttribute("email")] public str Email(str _email = email) { email = _email; return email; } [DataMemberAttribute("firstname")] public str FirstName(str _firstName = firstName) { firstName = _firstName; return firstName; } [DataMemberAttribute("lastname")] public str LastName(str _lastName = lastName) { lastName = _lastName; return lastName; } [DataMemberAttribute("store_id")] public int storeId(int _storeId = storeId) { storeId = _storeId; return storeId; } }
The program fetches the data correctly from the endpoint but fails in the course of serialization because of the names of some keys that are repetitive.
As with the id key, when I ran and stepped over my codes, I noticed that it was saving each field, but once it encounters the second id key in the address
array, it assigns the value to the id key of the main array as a second iteration and then fail afterwards, I think it's expecting the customer_id but sees
the group_id, then it fails giving the following error:
Microsoft.Dynamics.Ax.Xpp.ClrErrorException:JsonSerializationException: JsonSerializationException ---> Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'JsonSerializer.Root' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
How can I make it not assign the value of id in address to the main id of the array?