2012-04-25 18 views
28

Mam problem z RestSharp z deserializacją treści zwrotu na moje klasy. Z moich poszukiwań wydaje mi się, że robię to poprawnie. Wolałbym używać deserializera RestSharp, niż cofnąć się do innego pakietu, takiego jak Json.NET Newstonsoft.RestSharp nie deserializuje listy obiektów JSON, zawsze jest pusta

Co robie czyni wniosek API do GoToWebinar dla całej listy zaplanowanych seminaria:

var client = new RestClient(string.Format("https://api.citrixonline.com/G2W/rest/organizers/{0}/upcomingWebinars", "300000000000239000")); 
var request = new RestRequest(Method.GET); 
request.AddHeader("Authorization", "OAuth oauth_token=" + System.Configuration.ConfigurationManager.AppSettings["GoToWebinar"]); 
var response2 = client.Execute<List<RootObject>>(request); 

Jak widać Chciałbym uzyskać listę obiektów „RootObject” (jak pokazano poniżej). Otrzymuję następujące odpowiedzi JSON w response2.Content:

[ 
    { 
     "webinarKey":678470607, 
     "subject":"Easton's Wild Rice Cooking Demo", 
     "description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 
     "organizerKey":300000000000239551, 
     "times":[{"startTime":"2012-05-09T15:00:00Z","endTime":"2012-05-09T16:00:00Z"}], 
     "timeZone":"America/Denver" 
    }, 
    { 
     "webinarKey":690772063, 
     "subject":"Easton's Match Making Service", 
     "description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 
     "organizerKey":300000000000239551, 
     "times":[{"startTime":"2012-05-09T15:00:00Z","endTime":"2012-05-09T16:00:00Z"}], 
     "timeZone":"America/Denver" 
    } 
] 

stworzyłem następujące obiekty przy użyciu http://json2csharp.com wykorzystaniem wyników JSON powyżej:

public class RootObject 
{ 
    public int webinarKey { get; set; } 
    public string subject { get; set; } 
    public string description { get; set; } 
    public long organizerKey { get; set; } 
    public List<Time> times { get; set; } 
    public string timeZone { get; set; } 
} 

public class Time 
{ 
    public string startTime { get; set; } 
    public string endTime { get; set; } 
} 

Problemem jest response2.Data zawsze jest Null. Z jakiegoś powodu deserializacja nie powiodła się i nie wiem dlaczego. Moim celem jest, aby móc użyć pętli foreach do iterację wyników:

foreach(RootObject r in response2.Data) 
{ 
    lblGoToWebinar.Text += r.webinarKey.ToString() + ", "; 
} 

Wszelkie pomysły, dlaczego deserializacji się niepowodzeniem?

Z góry dziękuję!

+2

Czy można debugować i patrzeć na obiekt 'response2', aby zobaczyć, jaka jest wartość nieprzetworzona? Powinieneś zobaczyć, czy wystąpił błąd w debugerze. – agarcian

+1

Dziękuję @agarcian! Na podstawie twojej sugestii zacząłem przeszukiwać niektóre wewnętrzne błędy i odkryłem, że jest to widoczne w mojej odpowiedzi poniżej. –

+0

Cieszę się, że udało się! – agarcian

Odpowiedz

71

podstawie sugestią @ agarcian w powyższym google błąd:

restsharp Data at the root level is invalid. Line 1, position 1.

i znalazłem to forum: http://groups.google.com/group/restsharp/browse_thread/thread/ff28ddd9cd3dde4b

Zasadniczo, myliłem się założyć, że client.Execute szło, aby móc aby automatycznie wykryć typ zawartości zwrotnej. To musi być jawnie ustawione:

var request = new RestRequest(Method.GET); 
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; }; 

To może być cytowane jaśniej w dokumentacji RestSharp użytkownika. Mam nadzieję, że to pomoże komuś innemu!

+2

Określenie 'Method.GET' jest zbędne, czyż nie? (To jest domyślny typ metody) – ashes999

+0

@ ashes999, uzgodniono. –

+3

Zgodnie z wątkiem zalecane podejście to: 'client.AddHandler (" text/plain ", new JsonDeserializer())', to naprawdę powinno być w dokumentacji – Rowan

1

Późne przyjęcie: Musisz znaleźć numer aktualny Content-Type odpowiedzi, którą otrzymujesz. Serwer niekoniecznie odpowiada na dowolny typ zawartości z nagłówka Accept danego żądania. W przypadku interfejsów API firmy Google otrzymałem odpowiedź tekstową/zwykłą, więc ta advice from the group była dla mnie odpowiednia.

public T Execute<T>(string url, RestRequest request) where T : new() 
{ 
    var client = new RestClient(); 
    // tell RestSharp to decode JSON for APIs that return "Content-Type: text/plain" 
    client.AddHandler("text/plain", new JsonDeserializer()); 
    ... 

To także porządniej, jeśli można to zrobić w jednym miejscu, takich jak wspólne metody Execute powyżej, zamiast wymuszania typ odpowiedzi z OnBeforeDeserialization gdzie każde żądanie jest tworzony.

Powiązane problemy