问题背景:
我正在查询Amazons产品广告API,并尝试将JSON响应取消激活到C#对象。
问题:
代码尝试转换时收到反序列化错误。我无法解决哪个部分导致错误。以下是我收到的错误:
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.
代码:
以下C#是Newtonsoft尝试序列化的内容。
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:
我认为这是一个问题,因为我有一个单一的项目,而转换需要一个列表?
{
"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"
}
}
}
}
修改:
这是我用来创建一个转换器来处理单个Item对象和它们List的代码。
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();
}
}
答案 0 :(得分:2)
.Net小提琴:https://dotnetfiddle.net/9MACjN
您有多个问题:
您实际上错过了json中的结束}
。
您需要反序列化为包含Response
的父类(例如Items
)。
Items.Item
属性必须是Item
类型,而不是List<Item>
,正如David所说。
JsonProperty
属性根本不需要。
然后它有效。
答案 1 :(得分:2)
JSON中的Item
属性是普通对象,而不是对象列表。如果它应该是一个列表,那么JSON将用方括号括起来表示它是一个数组,例如:
"Item": [{ item1 }, { item2}, ... ]
因此您需要更改模型以匹配。例如:
public class Items
{
//snip
public Item Item { get; set; }
}