2015-11-22 3 views
0

Вопрос фона:JSON Десериализация - обрабатывать свойство, которое может быть массивом

Я запрашивая амазонки продукт Реклама API и пытается desearlize ответ 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" 
      } 
     } 
    } 
} 

EDIT:

Это код, который я использовал для создания конвертер для обработки как уникальный объект предмета и их список.

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

Покажите нам JSON, без этого мы не можем помочь. – DavidG

+0

@DavidG Добавлено ответ JSON – user1352057

+0

Похоже, что свойство 'Item' не является списком, сделайте его простым объектом:' public Item Item {get; задавать; } ' – DavidG

ответ

2

Свойство Item в JSON - это простой объект, а не список объектов. Если он должен был быть список, то JSON будет заключен в квадратные скобки, чтобы указать, что это массив, например .:

"Item": [{ item1 }, { item2}, ... ] 

Таким образом, вы должны изменить свою модель, чтобы соответствовать.Например:

public class Items 
{ 
    //snip 
    public Item Item { get; set; } 
} 
+0

Спасибо за ваш ответ. Обычно я получаю список элементов. В этом случае это единственный элемент, который выглядит проблемой? – user1352057

+0

Ну, это JSON не список, так что да, это проблема. Возможно, существуют разные API-вызовы, которые предоставляют разные JSON. – DavidG

+0

@ DavidG Большое спасибо за вашу помощь. В конце концов я это отсортировал. Это было, как я сказал, проблема, когда иногда свойство Items является единственным объектом, а другие - массивом. В конце концов я использовал класс JsonConverter в NewtonSoft и создал конвертер. Я добавлю код к исходному вопросу. – user1352057

2

.Net Fiddle: https://dotnetfiddle.net/9MACjN

Вы имели несколько вопросов:

  • Вы фактически отсутствующие закрытия } в вашем JSON.

  • Вам необходимо десериализовать родительский класс (например, Response), который содержит Items.

  • Недвижимость Items.Item должно быть типа Item, а не List<Item>, как сказал Дэвид.

  • JsonProperty Атрибуты не нужны вообще.

Тогда это работает.

+0

Я думаю, что OP уже сериализуется в' Items', иначе будет другая ошибка. Также атрибуты не являются проблемой, хотя они и избыточны. – DavidG

+0

@DavidG, хорошо, я обновил исправление. Это было несколько вопросов. – toddmo

+0

@toddmo благодарит за ваш ответ. Да, я пропустил последний {в моем JSON. Как работает AWS-ответ, иногда он возвращает список элементов, другие - время, когда это будет один объект Item, я добавил в свой вопрос, как я исправил проблему. Я удалю избыточные свойства JSON. Большое спасибо за ваш ответ. – user1352057

Смежные вопросы