2013-04-18 52 views
5

Tôi thực sự gặp vấn đề này trong 2 ngày, làm cách nào để lấy dữ liệu ra khỏi đối tượng json lồng nhau sâu.Nhận dữ liệu từ đối tượng json lồng nhau sâu

Tôi đã tìm thấy một công cụ json trực tuyến http://www.jsoneditoronline.org/http://jsonformat.com/ khi bạn dán json vào đó, hiển thị tất cả các mảng đối tượng v.v ..., vì vậy tôi có thể tìm hiểu dữ liệu và nhận thông tin mình muốn.

Khi tôi gỡ lỗi mã và đặt điểm ngắt trên: foreach (JToken data in rates.ToArray()) Tôi có thể xem dữ liệu sau, tôi không thể lấy dữ liệu, phụ thuộc vào những gì tôi thử tùy thuộc vào lỗi tôi nhận được, lỗi cuối cùng là .

Lỗi chuyển đổi giá trị "@rateChange" thành loại 'Web.UI.Controllers.HomeController + RateInfo'.

Không thể truyền hoặc chuyển đổi từ System.String sang Web.UI.Controllers.HomeController + RateInfo.

Bất kỳ trợ giúp nào được đánh giá cao.

Lớp học của tôi

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; } 
     } 

đang

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 
    } } 

===================== ======== Mã này hoạt động lấy dữ liệu ra khỏi mảng tóm tắt ============

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; 
     } 

Nhưng ngay khi tôi cố gắng đào sâu hơn vào dữ liệu, tôi không thể nhận được dữ liệu tôi cần

+0

Nếu bạn đang tìm kiếm này trong trình gỡ lỗi, những gì thực sự là những yếu tố của 'rates'. Đó là, là biểu hiện rất lớn lúc bắt đầu chính xác? – millimoose

+0

Hi @millimoose yes biểu thức là chính xác, json là những gì được trả về từ dịch vụ từ xa – CareerChange

+0

Dòng mã này là những gì ném lỗi. RateInfo rateInfo = JsonConvert.DeserializeObject (data.ToString()); – CareerChange

Trả lời

9

Hãy thử điều này thay vì:

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

Hi Phil, xin lỗi rằng ném lỗi này. Đã truy cập các giá trị JObject có giá trị khóa không hợp lệ: 0. Tên thuộc tính đối tượng được mong đợi. – CareerChange

+0

@CareerChange bạn đã thử cập nhật chưa? –

+0

Xin chào @Phil có, giờ đây bạn đã trả lại kết quả, cảm ơn bạn rất nhiều. Nếu bạn có thời gian, bạn có thể vui lòng cho tôi biết làm thế nào tôi sẽ lặp qua các mảng HotelSummary và nhận được tất cả dữ liệu, vì dữ liệu được trả về có mảng Msuiple HotelSummary. Không có vấn đề nếu bạn không thể, chỉ cần cảm ơn bạn một lần nữa để sửa chữa vấn đề này – CareerChange

0

phương pháp Phần mở rộng này sử dụng đệ quy để lặp qua một json lồng nhau sâu và tìm giá trị cho một 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; 
    } 

Làm thế nào để sử dụng:

var myValue = jsonObject.JsonValue<string>("propName"); 
    var numbValue = jsonObject.JsonValue<long?>("propName2") ?? 0; 
Các vấn đề liên quan