how to convert json code to getset property - c#

i have following code any one tell me how to convert this in class automatically .its very hard to convert code..please help me
[{
"karhoo_ref": "4325226970648863",
"supplier_company": "supplier1",
"booking_id": "32434234234",
"notes": "waited at southeast corner",
"status": "completed",
"vehicle": {
"vehicle_type": "suv",
"vehicle_id": "404",
"vehicle_plate": "BD51SMR",
"latitude": 40.73892,
"longitude": -73.9873663,
"eta_minutes": null,
"make": "Cadillac",
"model": "Escalade",
"color": "Black",
"eta_minutes": null,
"driver_id": "12121",
"driver_phone": "+14157854978",
"driver_first_name": "Sam",
"driver_last_name": "Smith",
"direction": {
"kph": 20,
"heading": 90
}
},
"total": 29.10,
"currency": "USD"
"price_components": [{
"component_name": "base rate",
"value": 27.10,
"description": "Base Rate"
}, {
"component_name": "parking",
"value": 0,
"description": "Parking"
}, {
"component_name": "tolls",
"value": 0,
"description": "Tolls"
}, {
"component_name": "meet greet",
"value": 0,
"description": "Meet & Greet",
"currency": "USD"
}, {
"component_name": "stop charges",
"value": 0,
"description": "Stop Charges"
}, {
"component_name": "wait time charges",
"value": 0,
"description": "Wait Time charges"
}, {
"component_name": "discount",
"value": 0,
"description": "Discount"
}, {
"component_name": "misc fee",
"value": 0,
"description": "Misc"
}, {
"component_name": "fuel surcharge",
"value": 0,
"description": "Fuel Surcharge"
}, {
"component_name": "service charge",
"value": 0,
"description": "Service Charge"
}, {
"component_name": "gratuity",
"value": 0,
"description": "Tips"
}, {
"component_name": "workers comp tax",
"value": 0,
"description": "NYC Workers Comp Tax"
}, {
"component_name": "tax",
"value": 2.00,
"description": "8.75% State"
}]
}, {
"karhoo_ref": "2825226970648863",
"supplier_company": "supplier2",
"booking_id": "ABC2155",
"notes": "waited at southeast corner",
"status": "completed",
"vehicle": {
"vehicle_type": "sedan",
"vehicle_id": "404",
"vehicle_plate": "BD51SMR",
"latitude": 40.73892,
"longitude": -73.9873663,
"eta_minutes": null,
"make": "Toyota",
"model": "Camery",
"color": "Black",
"driver_id": "12121",
"driver_phone": "4157854978",
"driver_first_name": "Sam",
"driver_last_name": "Smith",
"direction": {
"kph": 20,
"heading": 90
}
},
"total": 27.10,
"currency": "USD"
"price_components": [{
"component_name": "base rate",
"value": 27.10,
"description": "Base Rate"
}]
}]
i want like this.
public class ToLocation
{
public ToLocation()
{
address = new Address2();
}
public double latitude { get; set; }
public double longitude { get; set; }
public Address2 address { get; set; }
public object comment { get; set; }
public object airport { get; set; }
}

I think you should first check whether your string is a valid Json.
You may check below link to convert to class.
How to auto-generate a C# class file from a JSON object string

You're looking for this
Using the dynamic object type. Of course you can do some casting or data mapping later on.

Have a look at JSON.Net. Download the nuget package, than use:
dynamic dyn_json = JsonConvert.DeserializeObject(json);
After that you can iterate through the dynamic object and fill your C# object.

Related

Unable to Deserialize Json downloaded from a URL

I am trying to deserialize the JSON downloaded from the following site downloaded as RawData
Json from the Site
but following error is being thrown
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type '' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
I tried using following methods
Root[] roots= JsonConvert.DeserializeObject<Root[]>(jsonString);
and
var roots = JsonConvert.DeserializeObject<List<Root>>(jsonString);
I used following class
public class Root
{
public List<object> posts { get; set; }
public List<Person> persons { get; set; }
public List<Organization> organizations { get; set; }
public Meta meta { get; set; }
public List<Membership> memberships { get; set; }
public List<Event> events { get; set; }
public List<Area> areas { get; set; }
}
Following is the example JSON
"posts": [
],
"persons": [
{
"birth_date": "1957-08-09",
"contact_details": [
{
"type": "email",
"value": "hariomsingh.rathore#sansad.nic.in"
}
],
"email": "hariomsingh.rathore#sansad.nic.in",
"gender": "male",
"id": "0094ff14-ff6c-440a-96fc-f0bd68068569",
"identifiers": [
{
"identifier": "4655",
"scheme": "everypolitician_legacy"
},
{
"identifier": "hariomsinghrathore",
"scheme": "prsindia"
},
{
"identifier": "Q16897877",
"scheme": "wikidata"
}
],
"image": "http://164.100.47.132/mpimage/photo/4655.jpg",
"images": [
{
"url": "http://164.100.47.132/mpimage/photo/4655.jpg"
}
],
"links": [
{
"note": "Wikipedia (en)",
"url": "https://en.wikipedia.org/wiki/Hariom_Singh_Rathore"
}
],
"name": "Yavatmal-Washim",
"other_names": [
{
"lang": "en",
"name": "Yavatmal-Washim Lok Sabha constituency",
"note": "multilingual"
},
{
"lang": "hi",
"name": "यवतमाल-वाशिम लोक सभा निरà¥à¤µà¤¾à¤šà¤¨ कà¥à¤·à¥‡à¤¤à¥à¤°",
<?xml version="1.0" encoding="UTF-8"?> {
"posts": [
],
"persons": [
{
"birth_date": "1957-08-09",
"contact_details": [
{
"type": "email",
"value": "hariomsingh.rathore#sansad.nic.in"
}
],
"email": "hariomsingh.rathore#sansad.nic.in",
"gender": "male",
"id": "0094ff14-ff6c-440a-96fc-f0bd68068569",
"identifiers": [
{
"identifier": "4655",
"scheme": "everypolitician_legacy"
},
{
"identifier": "hariomsinghrathore",
"scheme": "prsindia"
},
{
"identifier": "Q16897877",
"scheme": "wikidata"
}
],
"image": "http://164.100.47.132/mpimage/photo/4655.jpg",
"images": [
{
"url": "http://164.100.47.132/mpimage/photo/4655.jpg"
}
],
"links": [
{
"note": "Wikipedia (en)",
"url": "https://en.wikipedia.org/wiki/Hariom_Singh_Rathore"
}
],
"name": "Rathore, Shri Hariom Singh",
"other_names": [
{
"lang": "en",
"name": "Hariom Singh Rathore",
"note": "multilingual"
},
{
"lang": "gu",
"name": "હરિઓમ સિંહ રાઠૌડ઼",
"note": "multilingual"
}
]
},
{
"birth_date": "1975-09-10",
"contact_details": [
{
"type": "email",
"value": "ravneetbittu#gmail.com"
}
],
"email": "ravneetbittu#gmail.com",
"family_name": "Singh",
"gender": "male",
"id": "01727319-7f2b-465b-825c-1d7a94a54f70",
"identifiers": [
{
"identifier": "4429",
"scheme": "everypolitician_legacy"
},
{
"identifier": "ravneetsingh",
"scheme": "prsindia"
},
],
"image": "http://164.100.47.132/mpimage/photo/4429.jpg",
"images": [
{
"url": "http://164.100.47.132/mpimage/photo/4429.jpg"
}
],
"links": [
{
"note": "Wikipedia (en)",
"url": "https://en.wikipedia.org/wiki/Ravneet_Singh_Bittu"
},
{
"note": "Wikipedia (pa)",
"url": "https://pa.wikipedia.org/wiki/ਰਵਨੀਤ_ਸਿੰਘ"
}
],
"name": "Singh, Shri Ravneet",
"other_names": [
"note": "multilingual"
},
{
"lang": "mr",
"name": "यवतमाळ-वाशिम (लोकसभा मतदारसंघ)",
"note": "multilingual"
},
{
"lang": "ta",
{
"lang": "en",
"name": "Ravneet Singh",
"note": "multilingual"
},
{
"lang": "te",
"name": "రవనీతౠసింగౠబిటà±à°Ÿà±‚",
"note": "multilingual"
}
]
},
{
"birth_date": "1958-09-07",
"contact_details": [
{
"type": "email",
"value": "bhairon.prasad#sansad.nic.in"
}
],
"email": "bhairon.prasad#sansad.nic.in",
"family_name": "Mishra",
"gender": "male",
"id": "02670d6a-6b60-4e7b-b0cd-b4fc7d6c3bca",
"identifiers": [
{
"identifier": "4626",
"scheme": "everypolitician_legacy"
},
{
"identifier": "Q16902096",
"scheme": "wikidata"
}
],
"image": "http://164.100.47.132/mpimage/photo/4626.jpg",
"images": [
{
"url": "http://164.100.47.132/mpimage/photo/4626.jpg"
}
],
"links": [
{
"note": "Wikipedia (en)",
"url": "https://en.wikipedia.org/wiki/Bhairon_Prasad_Mishra"
},
{
"note": "Wikipedia (hi)",
"url": "https://hi.wikipedia.org/wiki/भैरों_पà¥à¤°à¤¸à¤¾à¤¦_मिशà¥à¤°"
}
],
"name": "யவதà¯à®®à®¾à®³à¯-வாசிம௠மகà¯à®•à®³à®µà¯ˆà®¤à¯ தொகà¯à®¤à®¿",
"note": "multilingual"
}
],
"type": "constituency"
},
{
"id": "zahirabad",
"identifiers": [
{
"identifier": "Q8064692",
"scheme": "wikidata"
}
],
"name": "Zahirabad",
"other_names": [
{
"lang": "en",
"name": "Zahirabad Lok Sabha constituency",
"note": "multilingual"
},
{
"lang": "hi",
"name": "ज़हीराबाद लोक सभा निरà¥à¤µà¤¾à¤šà¤¨ कà¥à¤·à¥‡à¤¤à¥à¤° समà¥à¤ªà¤¾à¤¦à¤¨",
"note": "multilingual"
},
{
"lang": "mr",
"name": "à¤à¤¹à¥€à¤°à¤¾à¤¬à¤¾à¤¦ (लोकसभा मतदारसंघ)",
"note": "multilingual"
},
{
"lang": "ta",
"name": "ஜஹீராபாதà¯",
"note": "multilingual"
},
{
"lang": "te",
"name": "జహీరాబాదౠలోకసభ నియోజకవరà±à°—à°‚",
"note": "multilingual"
}
],
"type": "constituency"
}
]
}
Can any one please help me in doing that. Thanks.
Your json is not an array of roots. The json is a single object with multiple nested objects inside a single root.
{
"posts": [
],
"persons": [
{ "birth_date":
}
Since it's not returning an array of objects, you need to deserialize to a singular root.
var root = JsonConvert.DeserializeObject<Root>(jsonString);

How to assign same Json property name, one having value and other being null?

In the json response the property "data" is used as a List and in other places in the Json it is used as a string.. when its used in the List the property has some value when its using as a string the value is coming as null..
How to include both scenario here when I am deserialzing and serializing the json.. without running in to exception A member with the name 'data' already exists. Use the JsonPropertyAttribute to specify another name
public class Example
{
[JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
public List<Datum> Data { get; set; }
[JsonProperty("data", NullValueHandling = NullValueHandling.Include)]
public string Data { get; set; }
}
Here is what I tried to use a private property but not able to resolve the issue
[JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
public List<Datum> Data { get; set; }
[JsonProperty("data2", NullValueHandling = NullValueHandling.Include)]
private List<Datum> Data2 { set { Data = value; } }
Here is the Json
{
"adRoots": null,
"allowedTagTypes": [
0,
1,
4
],
"canEdit": true,
"filterConfigData": {
"config": [{
"extraData": null,
"id": "Endpoints.ID.SearchInProgress",
"title": "Search in Progress",
"type": 5
},
{
"data": null,
"extraData": null,
"id": "Endpoints.ID.Policies",
"source": {
"definition": "dbo",
"displayColumn": "Name",
"keyColumn": "Id",
"name": "Policies",
"type": 1
},
"title": "Policies",
"type": 3
},
{
"extraData": null,
"id": "Endpoints.ID.MACs",
"title": "MAC Addresses",
"type": 1
},
{
"data": [{
"name": "Endpoint Closed",
"value": 11
},
{
"name": "Endpoint Completed",
"value": 15
},
{
"name": "Endpoint Opened",
"value": 10
}
],
"extraData": null,
"id": "Endpoints.ID.ClientActivityState",
"source": {
"definition": "State",
"displayColumn": "Name",
"keyColumn": "Id",
"name": "ClientActivityState",
"type": 2
},
"title": "Client Activity State",
"type": 3
},
{
"data": [{
"name": "System Alarm",
"value": 3
},
{
"name": "System Audit",
"value": 2
}
],
"extraData": null,
"id": "Endpoints.ID.AceType",
"source": {
"definition": "AceType",
"displayColumn": "Name",
"keyColumn": "Id",
"name": "AceType",
"type": 2
},
"title": "ACL: ACE Type",
"type": 3
},
{
"extraData": null,
"id": "Endpoints.ID.AceWho",
"title": "ACL: Trustee",
"type": 1
},
{
"data": [{
"name": "Append Data",
"value": 4
},
{
"name": "Delete",
"value": 65536
},
{
"name": "Execute",
"value": 32
}
],
"extraData": null,
"id": "Endpoints.ID.AceRights",
"source": {
"definition": "AceRights",
"displayColumn": "Name",
"editor": "ViewModel",
"keyColumn": "Id",
"name": "AceRights",
"type": 2
},
"title": "ACL: Authorization",
"type": 3
},
{
"extraData": null,
"id": "Endpoints.ID.FilterTagName",
"title": "Tag Name",
"type": 1
},
{
"data": null,
"extraData": null,
"id": "Endpoints.ID.FilterTags",
"source": {
"definition": "dbo",
"displayColumn": "Name",
"keyColumn": "Id",
"name": "Tags",
"type": 1
},
"title": "Tags",
"type": 3
},
{
"extraData": null,
"id": "Endpoints.Name.EndpointName",
"title": "Endpoint Name",
"type": 1
},
{
"data": null,
"extraData": null,
"id": "Endpoints.Version.Version",
"title": "Endpoint Version",
"type": 1
},
{
"extraData": null,
"id": "Endpoints.Platform.Platform",
"title": "Endpoint Platform",
"type": 1
},
{
"data": [{
"name": "Desktop",
"value": 1
},
{
"name": "Server",
"value": 2
},
{
"name": "Unknown",
"value": 0
}
],
"extraData": null,
"id": "ELPlatformType",
"source": {
"displayColumn": "Name",
"keyColumn": "Id",
"name": "PlatformType",
"type": 2
},
"title": "Platform Type",
"type": 3
},
{
"extraData": null,
"id": "Endpoints.LastPoll.LastPoll",
"title": "Last Poll Time",
"type": 2
}
],
"pagedListItems": null
},
"forests": null,
"item": {
"disallowed": false,
"editPermissions": 0,
"endpointsCount": 0,
"filter": null,
"id": 404,
"ldapPaths": null,
"name": "tag",
"query": null,
"type": 0
}
}

Entity Framework Core Parent/Child Clean query with multi level child [duplicate]

This question already has an answer here:
Map category parent id self referencing table structure to EF Core entity
(1 answer)
Closed 2 years ago.
I have an issue on cleaning querying my parent child without repeating the children at its own root of the list.
Object
public class Office
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public bool Inactive { get; set; }
public int? ParentId { get; set; }
[ForeignKey("ParentId")]
public Office Parent { get; set; }
[InverseProperty("Parent")]
public virtual ICollection<Office> Children { get; set; }
}
}
The Query
public async Task<IEnumerable<Office>> GetOffices()
{
return await _context.Offices.Where(os => !os.Inactive)
.Include(o => o.Parent)
.Include(o => o.Children).ToListAsync();
}
And the result
{
"id": 5,
"name": "AA",
"inactive": false,
"parentId": null,
"parent": null,
"children": []
},
{
"id": 10,
"name": "BAA",
"inactive": false,
"parentId": 2,
"parent": {
"id": 2,
"name": "BA",
"inactive": false,
"parentId": null,
"parent": null,
"children": []
},
"children": [
{
"id": 1011,
"name": "BAAA",
"inactive": false,
"parentId": 10,
"children": []
}
]
},
{
"id": 1011,
"name": "BAAA",
"inactive": false,
"parentId": 10,
"parent": {
"id": 10,
"name": "BAA",
"inactive": false,
"parentId": 2,
"parent": {
"id": 2,
"name": "BA",
"inactive": false,
"parentId": null,
"parent": null,
"children": []
},
"children": []
},
"children": []
},
,
{
"id": 2,
"name": "BA",
"inactive": false,
"parentId": null,
"parent": null,
"children": [
{
"id": 10,
"name": "BAA",
"inactive": false,
"parentId": 2,
"children": [
{
"id": 1011,
"name": "BAAA",
"inactive": false,
"parentId": 10,
"children": []
}
]
}
]
}
This also has child objects at the root level so I tried this
public async Task<IEnumerable<Office>> GetOffices()
{
return await _context.Offices.Where(os => !os.Inactive && !os.ParentId.HasValue).Include(o => o.Parent).Include(o => o.Children).ToListAsync();
}
And this is the result of the other query
{
"id": 5,
"name": "AA",
"inactive": false,
"parentId": null,
"parent": null,
"children": []
},
{
"id": 2,
"name": "BA",
"inactive": false,
"parentId": null,
"parent": null,
"children": [
{
"id": 10,
"name": "BAA",
"inactive": false,
"parentId": 2,
"children": null
}
]
}
This leaves out id 1010 BAAA child object. Idealy I would like to have it come out as
{
"id": 5,
"name": "AA",
"inactive": false,
"parentId": null,
"parent": null,
"children": []
},
{
"id": 2,
"name": "BA",
"inactive": false,
"parentId": null,
"parent": null,
"children": [
{
"id": 10,
"name": "BAA",
"inactive": false,
"parentId": 2,
"children": [
{
"id": 1011,
"name": "BAAA",
"inactive": false,
"parentId": 10,
"children": []
}
]
}
]
}
No matter how I stack the query I can't seem to get this to display this way. Is there a way to adjust the query to allow this or an easy post query command to trim only the root level objects that are a child?
If you want limited number of child levels (2 in this example) fetched you can try:
await _context.Offices
.Where(os => !os.Inactive && !os.ParentId.HasValue)
.Include(o => o.Parent)
.Include(o => o.Children)
.ThenInclude(o => o.Children)
.ToListAsync()

How to add sorting for a *Text Field to ElasticSearch Query

NOTE: An answer was found, see the end of this post and the comments for more information.
ElasticSearch (ver 6) is my kryptonite. I have been trying to add a sorting to a query for far too long and only getting errors in response:
No mapping
Fielddata is disabled on text fields by default. Set fielddata=true ...
when I try to set "fielddata=true" ... I get more errors
[field_sort] unknown field [fielddata], parser not found
I've tried ingore_unmapped and get the same "unknown field" error.
The ES documentation is so generic that it is unhelpful, and nothing here on SO has helped... I've looked at/read after running into various errors
https://stackoverflow.com/a/17051944/10358406
unknown field [dest], parser not found- error coming while reindexing
Elasticsearch: Expected field name but got START_OBJECT
how to set fielddata=true in kibana
So now...
Here is my current query that I use through Postman. I use Nest in my C# project to build this up. I know how to build queries if I can get the json structure right in Postman:
{
"from": 0,
"size": 50,
"aggs": {
"specs": {
"nested": {
"path": "specs"
},
"aggs": {
"names": {
"terms": {
"field": "specs.name",
"size": 10
},
"aggs": {
"specValues": {
"terms": {
"field": "specs.value",
"size": 10
}
}
}
}
}
}
},
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"Id": {
"value": 1
}
}
}
],
"must_not": [
{
"terms": {
"partId": []
}
}
],
"should": [
{
"terms": {
"picCode": [
"b02"
]
}
},
{
"terms": {
"partId": []
}
}
]
}
}
}
}
}
The results I get back are like this:
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 281,
"max_score": 1,
"hits": [
{
"_index": "09812734",
"_type": "part",
"_id": "1234:1",
"_score": 1,
"_source": {
"id": "1234:1",
"partId": 1234,
"mcfCostCenterId": 1,
"oemCode": "ABC",
"oemDescription": "Blah blah blah",
"oemPartCode": "123456",
"picCode": "B02",
"description": "other blah blah",
"isServiceable": false,
"marketingDescription": "this thing does stuff"",
"salesVolume": 0,
"searchSortOrder": 0,
"catalogSortOrders": [],
"specs": [
{
"name": "Color",
"value": "NA"
},
{
"name": "Diameter",
"value": "7.0000"
},
{
"name": "OtherSpec",
"value": "Q"
},
{
"name": "LastSpec",
"value": "FuBar"
}
]
}
}
]
},
"aggregations": {
"specs": {
"doc_count": 18,
"names": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Length",
"doc_count": 4,
"specValues": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "2",
"doc_count": 1
},
{
"key": "3",
"doc_count": 1
},
{
"key": "8",
"doc_count": 1
}
]
}
}
]
}
}
}
}
I need to sort on description or salesVolume in the results.
We have another query that does sorting, so I used that same code for this query, but get the above errors. That code builds up the json as follows:
{
"from": 0,
"size": 50,
"sort": [
{
"foo.bar": {
"missing": "_last",
"order": "desc",
"nested_filter": {
"term": {
"foo.bar": {
"value": "frankenstein"
}
}
},
"nested_path": "_source"
}
}
],
"aggs": {
"specs": {
"nested": {
"path": "specs"
...
As I try to edit that to make it relevant to this search, I just get errors and no results.
EDIT:
So, getting "salesVolume" is pretty easy because it isn't a text field.
{
"from": 0,
"size": 50,
"sort": [
{
"salesVolume": {
"missing": "_last",
"order": "desc"
}
}
],
"aggs": {
...
This sets up a sort order no problem. So, the crux is text... I just can't figure out where to set the fielddata to true without erroring out.
EDIT 2:
In my DTO I have the field already set up with the keyword attribute.
public class MyClass
{
public string Id
[Text]
public string ThisCode
[Keyword]
public string MySortableTextField
... //and so forth
}
The search will still not perform and errors out.
ANSWER:
^^^ The Keyword attribute worked. I was not placing this in the right project. We have a project that builds out all our db indexes and that was still using the Text attribute. Once a indexing was redone then I was able to apply the sort order without errors.

JSON Deserialization - handle property that can be a array

Question Background:
I am querying Amazons Product Advertising API and trying to desearlize the JSON response to a C# object.
The Issue:
I have received a deserialization error when the code attempts the conversion. I can't quite work out which part is causing the error though. The following shows the error I'm receiving:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type'System.Collections.Generic.List`1[ShoppingComparisonEngine.AWS.AwsCommon.Item]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'Items.Item.ASIN', line 1, position 612.
The code:
The following C# are what the Newtonsoft is attempting to serialize to.
Item.cs:
public class Item
{
[JsonProperty("asin")]
public string ASIN { get; set; }
[JsonProperty("parentasin")]
public string ParentASIN { get; set; }
[JsonProperty("detailpageurl")]
public string DetailPageURL { get; set; }
[JsonProperty("salesrank")]
public string SalesRank { get; set; }
[JsonProperty("smallimage")]
public SmallImage SmallImage { get; set; }
[JsonProperty("mediumimage")]
public MediumImage MediumImage { get; set; }
[JsonProperty("largeimage")]
public LargeImage LargeImage { get; set; }
[JsonProperty("imagesets")]
public ImageSets ImageSets { get; set; }
[JsonProperty("itemattributes")]
public ItemAttributes ItemAttributes { get; set; }
[JsonProperty("offersummary")]
public OfferSummary OfferSummary { get; set; }
[JsonProperty("offers")]
public Offers Offers { get; set; }
}
Items.cs:
public class Items
{
[JsonProperty("totalresults")]
public string TotalResults { get; set; }
[JsonProperty("totalpages")]
public string TotalPages { get; set; }
[JsonProperty("moresearchresultsurl")]
public string MoreSearchResultsUrl { get; set; }
[JsonProperty("item")]
public List<Item> Item { get; set; }
}
JSON:
I believe this is an issue with the fact I have a singe Item whereas the conversion requires a list of them?
{
"Items": {
"xmlns": "http://webservices.amazon.com/AWSECommerceService/2011-08-01",
"Request": {
"IsValid": "True",
"ItemSearchRequest": {
"Availability": "Available",
"Condition": "New",
"ItemPage": "6",
"Keywords": "champagne bucket",
"ResponseGroup": [
"Medium",
"Offers"
],
"SearchIndex": "HomeGarden"
}
},
"TotalResults": "51",
"TotalPages": "6",
"MoreSearchResultsUrl": "http://www.amazon.co.uk/gp/redirect.html?linkCode=xm2&SubscriptionId=AKIAIFERUZJXWJ3Y2USA&location=http%3A%2F%2Fwww.amazon.co.uk%2Fgp%2Fsearch%3Fkeywords%3Dchampagne%2Bbucket%26url%3Dsearch-alias%253Doutdoor&tag=compar0c2-21&creative=12734&camp=2025",
"Item": {
"ASIN": "B00IYO4HRQ",
"DetailPageURL": "http://www.amazon.co.uk/Bottle-Holder-Accessories-Garden-Maintenance/dp/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00IYO4HRQ",
"ItemLinks": {
"ItemLink": [
{
"Description": "Add To Wishlist",
"URL": "http://www.amazon.co.uk/gp/registry/wishlist/add-item.html%3Fasin.0%3DB00IYO4HRQ%26SubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ"
},
{
"Description": "Tell A Friend",
"URL": "http://www.amazon.co.uk/gp/pdp/taf/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ"
},
{
"Description": "All Customer Reviews",
"URL": "http://www.amazon.co.uk/review/product/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ"
},
{
"Description": "All Offers",
"URL": "http://www.amazon.co.uk/gp/offer-listing/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ"
}
]
},
"SmallImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"MediumImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL160_.jpg",
"Height": {
"Units": "pixels",
"value": "160"
},
"Width": {
"Units": "pixels",
"value": "160"
}
},
"LargeImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL.jpg",
"Height": {
"Units": "pixels",
"value": "300"
},
"Width": {
"Units": "pixels",
"value": "300"
}
},
"ImageSets": {
"ImageSet": [
{
"Category": "swatch",
"SwatchImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL30_.jpg",
"Height": {
"Units": "pixels",
"value": "30"
},
"Width": {
"Units": "pixels",
"value": "30"
}
},
"SmallImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"ThumbnailImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"TinyImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL110_.jpg",
"Height": {
"Units": "pixels",
"value": "110"
},
"Width": {
"Units": "pixels",
"value": "110"
}
},
"MediumImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL._SL160_.jpg",
"Height": {
"Units": "pixels",
"value": "160"
},
"Width": {
"Units": "pixels",
"value": "160"
}
},
"LargeImage": {
"URL": "http://ecx.images-amazon.com/images/I/31lBLzzkQlL.jpg",
"Height": {
"Units": "pixels",
"value": "300"
},
"Width": {
"Units": "pixels",
"value": "300"
}
}
},
{
"Category": "primary",
"SwatchImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL30_.jpg",
"Height": {
"Units": "pixels",
"value": "30"
},
"Width": {
"Units": "pixels",
"value": "30"
}
},
"SmallImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"ThumbnailImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL75_.jpg",
"Height": {
"Units": "pixels",
"value": "75"
},
"Width": {
"Units": "pixels",
"value": "75"
}
},
"TinyImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL110_.jpg",
"Height": {
"Units": "pixels",
"value": "110"
},
"Width": {
"Units": "pixels",
"value": "110"
}
},
"MediumImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL._SL160_.jpg",
"Height": {
"Units": "pixels",
"value": "160"
},
"Width": {
"Units": "pixels",
"value": "160"
}
},
"LargeImage": {
"URL": "http://ecx.images-amazon.com/images/I/31cr9r7XChL.jpg",
"Height": {
"Units": "pixels",
"value": "300"
},
"Width": {
"Units": "pixels",
"value": "300"
}
}
}
]
},
"ItemAttributes": {
"Brand": "Garden at Home",
"EAN": "5971458914919",
"EANList": {
"EANListElement": "5971458914919"
},
"Feature": "Wine Bottle Holder and Cooler Bag Wine Accessories",
"Label": "Outdoor&Lawn",
"Manufacturer": "Outdoor&Lawn",
"MPN": "GG_89773368",
"PartNumber": "GG_89773368",
"ProductGroup": "Lawn & Patio",
"ProductTypeName": "OUTDOOR_LIVING",
"Publisher": "Outdoor&Lawn",
"Studio": "Outdoor&Lawn",
"Title": "Wine Bottle Holder and Cooler Bag Wine Accessories, Garden, Lawn, Maintenance"
},
"OfferSummary": {
"LowestNewPrice": {
"Amount": "5220",
"CurrencyCode": "GBP",
"FormattedPrice": "£52.20"
},
"TotalNew": "1",
"TotalUsed": "0",
"TotalCollectible": "0",
"TotalRefurbished": "0"
},
"Offers": {
"TotalOffers": "1",
"TotalOfferPages": "1",
"MoreOffersUrl": "http://www.amazon.co.uk/gp/offer-listing/B00IYO4HRQ%3FSubscriptionId%3DAKIAIFERUZJXWJ3Y2USA%26tag%3Dcompar0c2-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3DB00IYO4HRQ",
"Offer": {
"OfferAttributes": {
"Condition": "New"
},
"OfferListing": {
"OfferListingId": "kif7varXuUaD7y55JfdjU7h3YCJvQokyXfgDIWvxOx6%2FqiMbxoPBsyFWCmgo8pbOqZNcezFUCBSdlx3JtRpEpe4Tu7VGv9zncLOYVmoSOUEDNQf1rrKJzZVCjnVPRCKyes0GSlEzlx%2Faht4%2FtjijlvCo14Z3CCcm",
"Price": {
"Amount": "5800",
"CurrencyCode": "GBP",
"FormattedPrice": "£58.00"
},
"SalePrice": {
"Amount": "5220",
"CurrencyCode": "GBP",
"FormattedPrice": "£52.20"
},
"AmountSaved": {
"Amount": "580",
"CurrencyCode": "GBP",
"FormattedPrice": "£5.80"
},
"PercentageSaved": "10",
"Availability": "Usually dispatched within 1-2 business days",
"AvailabilityAttributes": {
"AvailabilityType": "now",
"MinimumHours": "24",
"MaximumHours": "48"
},
"IsEligibleForSuperSaverShipping": "0",
"IsEligibleForPrime": "0"
}
}
},
"EditorialReviews": {
"EditorialReview": {
"Source": "Product Description",
"Content": "Ice Bucket Bag and Wine Cooler This unique Ice Bucket Bag is attractive and very durable. It is ideal for transporting wine to a friend, hostess or party and arriving with it perfectly chilled.Transparent and waterproof, this wine or Champagne bag also makes a super, space-saving ice bucket that simply folds away after use. It is especially ideal for a picnic or BBQ as it can fold for easy transport and is unbreakableIn addition, this bag makes a great party favor - comes with pocket for place card, business card or gift card. Heavy duty plastic measures 4\" x 4\" x 10\" when open, gift card slot measures 2\" x 3\".",
"IsLinkSuppressed": "0"
}
}
}
}
EDIT:
This is the code I used to create a Converter to handle both a singular Item object and a List of them.
public class ItemConverter:JsonConverter
{
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
List<Item> items = serializer.Deserialize<List<Item>>(reader);
return items;
}
else
{
Item itemList = serializer.Deserialize<Item>(reader);
return new List<Item>(new[] { itemList });
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
The Item property in the JSON is a plain object, not a list of objects. If it was supposed to be a list, then the JSON would be enclosed in square brackets to indicate it is an array, e.g.:
"Item": [{ item1 }, { item2}, ... ]
So you need to change your model to match. For example:
public class Items
{
//snip
public Item Item { get; set; }
}
.Net Fiddle: https://dotnetfiddle.net/9MACjN
You had multiple issues:
You are actually missing the closing } in your json.
You need to deserialize into a parent class (e.g., Response) that contains Items.
The Items.Item property needs to be of type Item, not List<Item>, as David said.
JsonProperty attributes are not needed at all.
Then it works.

Categories