2013-04-18 4 views
5

Я действительно застрял в этой проблеме сейчас в течение 2 дней, как я могу получить данные из глубоко вложенного объекта json.Получение данных из глубоко вложенного объекта json

Я нашел онлайн-инструменты json http://jsonformat.com/, который, когда вы вставляете в него json, показывает все массивы объектов и т. Д., Поэтому я могу выкопать данные и получить необходимую информацию.

Когда я отлаживаю код и помещаю точку останова на: foreach (JToken data in rates.ToArray()) Я могу видеть данные, которые мне нужны, я просто не могу получить данные, зависит от того, что я пытаюсь, зависит от ошибки, которую я получаю, последняя ошибка была ,

Ошибка преобразования значения "@rateChange" к типу 'Web.UI.Controllers.HomeController + Рейтинфо'.

Невозможно выполнить преобразование или преобразование из System.String в Web.UI.Controllers.HomeController + RateInfo.

Любая помощь с этим очень ценится.

Мой класс

public class RateInfo 
     { 
      public string RateChange { get; set; } 
      public string Promo { get; set; } 
      public string PriceBreakdown { get; set; } 
      public bool NonRefundable { get; set; } 
      public string RateType { get; set; } 
      public int CurrentAllotment { get; set; } 
      public int? PromoId { get; set; } 
      public string PromoDescription { get; set; } 
      public string PromoType { get; set; } 
     } 

код

IList<JToken> rates = root["HotelListResponse"]["HotelList"]["HotelSummary"][0]["RoomRateDetailsList"]["RoomRateDetails"]["RateInfos"]["RateInfo"].Children().ToList(); 


         IList<RateInfo> info = new List<RateInfo>(); 
         foreach (JToken data in rates.ToArray()) 
         { 
          RateInfo rateInfo = JsonConvert.DeserializeObject<RateInfo>(data.ToString()); 
          info.Add(rateInfo); 
         } 

Json

{ "HotelListResponse" : { "HotelList" : { "@activePropertyCount" : "168", 
      "@size" : "2", 
      "HotelSummary" : [ { "@order" : "0", 
       "@ubsScore" : "360017", 
       "RoomRateDetailsList" : { "RoomRateDetails" : { "RateInfos" : { "@size" : "1", 
          "RateInfo" : { "@priceBreakdown" : "true", 
           "@promo" : "true", 
           "@rateChange" : "true", 
           "ChargeableRateInfo" : { "@averageBaseRate" : "68.62333", 
            "@averageRate" : "68.62333", 
            "@commissionableUsdTotal" : "205.87", 
            "@currencyCode" : "USD", 
            "@grossProfitOffline" : "14.06", 
            "@grossProfitOnline" : "27.44", 
            "@maxNightlyRate" : "77.87", 
            "@nightlyRateTotal" : "205.87", 
            "@total" : "205.87", 
            "NightlyRatesPerRoom" : { "@size" : "3", 
             "NightlyRate" : [ { "@baseRate" : "77.87", 
               "@promo" : "false", 
               "@rate" : "77.87" 
              }, 
              { "@baseRate" : "64.0", 
               "@promo" : "false", 
               "@rate" : "64.0" 
              }, 
              { "@baseRate" : "64.0", 
               "@promo" : "false", 
               "@rate" : "64.0" 
              } 
              ] 
             } 
            }, 
           "RoomGroup" : { "Room" : { "numberOfAdults" : 2, 
             "numberOfChildren" : 0, 
             "rateKey" : "f82ab843-49ee-481a-b53a-71647592b183" 
             } }, 
           "currentAllotment" : 0, 
           "nonRefundable" : true, 
           "promoDescription" : "Advance Purchase Special - non-refundable", 
           "promoId" : 200827770, 
           "promoType" : "Standard", 
           "rateType" : "MerchantStandard" 
           } 
          }, 
         "ValueAdds" : { "@size" : "1", 
          "ValueAdd" : { "@id" : "2048", 
           "description" : "Free Wireless Internet" 
           } 
          }, 
         "expediaPropertyId" : 3084588, 
         "maxRoomOccupancy" : 3, 
         "minGuestAge" : 0, 
         "propertyAvailable" : true, 
         "propertyRestricted" : false, 
         "quotedRoomOccupancy" : 2, 
         "rateCode" : 200371945, 
         "roomDescription" : "Standard Room with King size bed", 
         "roomTypeCode" : 477014 
         } }, 
       "address1" : "Stone Cellar Road", 
       "address2" : "High Usworth Newcastle", 
       "airportCode" : " ", 
       "amenityMask" : 18063491, 
       "city" : "Washington", 
       "confidenceRating" : 90, 
       "countryCode" : "GB", 
       "deepLink" : "http://travel.ian.com/index.jsp?pageName=hotAvail&cid=55505&hotelID=340461&mode=2&numberOfRooms=1&room-0-adult-total=2&room-0-child-total=0&arrivalMonth=11&arrivalDay=12&departureMonth=11&departureDay=15&showInfo=true&locale=en_US&currencyCode=USD", 
       "highRate" : 77.870000000000005, 
       "hotelId" : 340461, 
       "hotelInDestination" : true, 
       "hotelRating" : 3, 
       "latitude" : 54.922739999999997, 
       "locationDescription" : "Near Washington Old Hall", 
       "longitude" : -1.5342899999999999, 
       "lowRate" : 64, 
       "name" : "Mercure Newcastle George Washington Hotel Golf and Spa", 
       "postalCode" : "NE37 1PH", 
       "propertyCategory" : 1, 
       "proximityDistance" : 1.4710813, 
       "proximityUnit" : "MI", 
       "rateCurrencyCode" : "USD", 
       "shortDescription" : "<p><b>Location. </b> <br />Mercure Newcastle George Washington Hotel Golf and Spa is a business-friendly hotel located in Washington, close to Washington Old Hall, Angel of the North, and WWT", 
       "supplierType" : "E", 
       "thumbNailUrl" : "/hotels/4000000/3090000/3084600/3084588/3084588_84_t.jpg", 
       "tripAdvisorRating" : 3.5, 
       "tripAdvisorRatingUrl" : "http://www.tripadvisor.com/img/cdsi/img2/ratings/traveler/3.5-12345-4.gif", 
       "tripAdvisorReviewCount" : 215 
       }, 
       { "@order" : "1", 
       "@ubsScore" : "258461", 
       "RoomRateDetailsList" : { "RoomRateDetails" : { "RateInfos" : { "@size" : "1", 
          "RateInfo" : { "@priceBreakdown" : "true", 
           "@promo" : "false", 
           "@rateChange" : "true", 
           "ChargeableRateInfo" : { "@averageBaseRate" : "54.83667", 
            "@averageRate" : "54.83667", 
            "@commissionableUsdTotal" : "164.51001", 
            "@currencyCode" : "USD", 
            "@grossProfitOffline" : "11.69", 
            "@grossProfitOnline" : "22.38", 
            "@maxNightlyRate" : "63.47", 
            "@nightlyRateTotal" : "164.51001", 
            "@total" : "164.51", 
            "NightlyRatesPerRoom" : { "@size" : "3", 
             "NightlyRate" : [ { "@baseRate" : "50.52", 
               "@promo" : "false", 
               "@rate" : "50.52" 
              }, 
              { "@baseRate" : "50.52", 
               "@promo" : "false", 
               "@rate" : "50.52" 
              }, 
              { "@baseRate" : "63.47", 
               "@promo" : "false", 
               "@rate" : "63.47" 
              } 
              ] 
             } 
            }, 
           "RoomGroup" : { "Room" : { "numberOfAdults" : 2, 
             "numberOfChildren" : 0, 
             "rateKey" : "f82ab843-49ee-481a-b53a-71647592b183" 
             } }, 
           "currentAllotment" : 0, 
           "nonRefundable" : true, 
           "rateType" : "MerchantStandard" 
           } 
          }, 
         "expediaPropertyId" : 901118, 
         "maxRoomOccupancy" : 2, 
         "minGuestAge" : 0, 
         "propertyAvailable" : true, 
         "propertyRestricted" : false, 
         "quotedRoomOccupancy" : 2, 
         "rateCode" : 200369466, 
         "roomDescription" : "Standard room with double bed - Book early & Save", 
         "roomTypeCode" : 162976 
         } }, 
       "address1" : "Emerson Road", 
       "address2" : "District 5", 
       "airportCode" : "NCL", 
       "amenityMask" : 1507328, 
       "city" : "Washington", 
       "confidenceRating" : 85, 
       "countryCode" : "GB", 
       "deepLink" : "http://travel.ian.com/index.jsp?pageName=hotAvail&cid=55505&hotelID=207631&mode=2&numberOfRooms=1&room-0-adult-total=2&room-0-child-total=0&arrivalMonth=11&arrivalDay=12&departureMonth=11&departureDay=15&showInfo=true&locale=en_US&currencyCode=USD", 
       "highRate" : 63.469999999999999, 
       "hotelId" : 207631, 
       "hotelInDestination" : true, 
       "hotelRating" : 2, 
       "latitude" : 54.895090000000003, 
       "locationDescription" : "Near Washington Old Hall", 
       "longitude" : -1.55661, 
       "lowRate" : 50.520000000000003, 
       "name" : "Campanile Washington Newcastle Upon Tyne", 
       "postalCode" : "NE37 1LB", 
       "propertyCategory" : 1, 
       "proximityDistance" : 1.2526573000000001, 
       "proximityUnit" : "MI", 
       "rateCurrencyCode" : "USD", 
       "shortDescription" : "<p><b>Location. </b> <br />Campanile Washington Newcastle Upon Tyne is located in Washington, close to Washington Old Hall, Angel of the North, and WWT Washington Wetland Centre. Additional area", 
       "supplierType" : "E", 
       "thumbNailUrl" : "/hotels/1000000/910000/901200/901118/901118_20_t.jpg", 
       "tripAdvisorRating" : 3.5, 
       "tripAdvisorRatingUrl" : "http://www.tripadvisor.com/img/cdsi/img2/ratings/traveler/3.5-12345-4.gif", 
       "tripAdvisorReviewCount" : 55 
       } 
      ] 
     }, 
     "cacheKey" : "4ef59f3e:13e1c495694:-6e28", 
     "cacheLocation" : "10.186.168.74:7301", 
     "cachedSupplierResponse" : { "@cachedTime" : "0", 
      "@candidatePreptime" : "100", 
      "@matchedCurrency" : "true", 
      "@matchedLocale" : "true", 
      "@otherOverheadTime" : "3", 
      "@supplierCacheTolerance" : "MED", 
      "@supplierRequestNum" : "118", 
      "@supplierResponseNum" : "2", 
      "@supplierResponseTime" : "468", 
      "@tpidUsed" : "5200" 
     }, 
     "customerSessionId" : "0ABAA84A-59F3-E913-E1C2-495694906E33", 
     "moreResultsAvailable" : true, 
     "numberOfRoomsRequested" : 1 
    } } 

===================== ======== Этот код работает с получением данных из сводного массива =============

public class Hotelsummary 
    { 
     public string Name     { get; set; } 
     public string Address1    { get; set; } 
     public string Address2    { get; set; } 
     public string City     { get; set; } 
     public string PostalCode   { get; set; } 
     public string CountryCode   { get; set; } 
     public string ThumbNailUrl   { get; set; } 
     public string ShortDescription  { get; set; } 
     public double HotelRating   { get; set; } 
     public double TripAdvisorRating  { get; set; } 
     public string RateCurrencyCode  { get; set; } 
    } 


public IEnumerable<Hotelsummary> GetHotelsForLocationSearch() 
     { 
      var hotelDetails = GetHotelsFromEan.GetListOfHotels(); 
      var root = JObject.Parse(hotelDetails.ToString()); 
      IList<JToken> hotels = root["HotelListResponse"]["HotelList"]["HotelSummary"].Children().ToList(); 
      IList<Hotelsummary> hotelsummaries = hotels.Select(result => JsonConvert 
                      .DeserializeObject<Hotelsummary>(
                       result.ToString())).ToList(); 
      return hotelsummaries; 
     } 

Но как только я пытаюсь углубиться в данные, я не могу получить данные мне нужно

+0

Если вы смотрите на это в отладчике, каков на самом деле элементы 'rates'. То есть, огромное выражение в начале правильное? – millimoose

+0

Привет @millimoose да выражение правильное, json - это то, что возвращается с удаленного сервиса – CareerChange

+0

Эта строка кода является тем, что вызывает ошибку. RateInfo rateInfo = JsonConvert.DeserializeObject (data.ToString()); – CareerChange

ответ

9

Попробуйте вместо этого:

IList<JToken> rates = root["HotelListResponse"]["HotelList"]["HotelSummary"][0]["RoomRateDetailsList"]["RoomRateDetails"]["RateInfos"].Children().ToList(); 

EDIT:

var rateInfo = json["HotelListResponse"]["HotelList"]["HotelSummary"][0]["RoomRateDetailsList"]["RoomRateDetails"]["RateInfos"]["RateInfo"]; 

var result =JsonConvert.DeserializeObject<RateInfo>(rateInfo .ToString()); 
+0

Привет, Фил, извините, что эта ошибка вызывает. Доступ к значениям JObject с недопустимым значением ключа: 0. Ожидается имя свойства объекта. – CareerChange

+0

@CareerChange вы пробовали обновление? –

+0

Привет @Phil да, теперь он возвращает результаты, спасибо вам очень. Если у вас есть время, не могли бы вы рассказать мне, как я буду проходить через массивы HotelSummary и получить все данные, так как возвращаемые данные имеют множественные массивы HotelSummary. Нет проблем, если вы не можете, просто благодарю вас за исправление этой проблемы. – CareerChange

0

Этот метод расширения использует рекурсию для циклического перехода через глубокий вложенный json и находит значение для jProperty.

 public static TType JsonValue<TType>(this JObject obj, string key) 
    { 
     object result = null; //default to null if nothing is found 

     foreach (var item in obj) 
     { 
      var token = item; 

      if (token.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)) 
      { 
       result = token.Value.ToObject<TType>(); //return the value found 
       break; 
      } 

      if (!obj[token.Key].Children().Any()) 
       continue; 

       var jt = obj[token.Key].ToString(); 

       if (!jt.StartsWith("[")) 
       { 
        result = JsonValue<TType>(JObject.Parse(jt), key); 
       } 
       else 
       { 
        obj[token.Key].Children().ToList().ForEach(x => 
        { 
         //only the first match will be returned 
         result = JsonValue<TType>(JObject.Parse(x.ToString()), key); 
        }); 
       } 

      if (result != null) 
       break; 

     } 

     return (TType)result; 
    } 

Как использовать:

var myValue = jsonObject.JsonValue<string>("propName"); 
    var numbValue = jsonObject.JsonValue<long?>("propName2") ?? 0; 
Смежные вопросы