2016-09-10 5 views
-2

Это связано с моим вопросом HTTPClient Buffer Exceeded 2G; Cannot write more bytes to the buffer, но это совсем другое, что ИМО требует отдельного вопроса.NewtonSoft Json Invalid Cast Excception

В другом вопросе, я пытаюсь выяснить, как бороться с разрывом буфера запросов 2G. Идея заключалась в использовании потоковой передачи, но мне нужно десериализовать. В разговоре с профессором Google я обнаружил, что мне нужно использовать TextReader для потоковой/десериализации. поэтому мой код для этого:

public async Task<API_Json_Special_Feeds.RootObject> walMart_Special_Feed_Lookup(string url) 
    { 
     special_Feed_Lookup_Working = true; 
     HttpClientHandler handler = new HttpClientHandler() 
     { 
      AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate 
     }; 
     using (HttpClient http = new HttpClient(handler)) 
     { 

      http.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip")); 
      http.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite); 
      url = String.Format(url); 
      using (var response = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)) 
      { 
       Console.WriteLine(response); 
       var serializer = new JsonSerializer(); 

       using (StreamReader sr = new StreamReader(await response.Content.ReadAsStreamAsync())) 
       { 
        using (var jsonTextReader = new JsonTextReader(sr)) 
        { 
         API_Json_Special_Feeds.RootObject root = (API_Json_Special_Feeds.RootObject)serializer.Deserialize(jsonTextReader); 
         return root; 
        } 
       } 
      } 
     } 
    } 

Теперь, как вы можете видеть, тип возврата строго типизирован. Возвращается тип метода. Теперь я иду к вызывающей линии:

API_Json_Special_Feeds.RootObject Items = await net.walMart_Special_Feed_Lookup(specialFeedsURLs[i].Replace("{apiKey}", Properties.Resources.API_Key_Walmart)); 

Итак, мы соответствующие типы API_Json_Special_Feeds.RootMethod все вокруг.

При запуске вызывающей линии бросает InvalidCastException:

нежелательный результат:

Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'RootObject' 

Я проверил в конце метода перед возвращением, и результат действительно отлит из объект перед API_Json_Special_Feeds.RootMethod перед возвратом.

Вопрос: где-то между высказыванием возвратного и вызывающей линии, объект возвращается преобразовывается из API_Json_Special_Feeds.RootMethod к Newtonsoft.Json.Linq.JObject. Я не могу отлаживать его, поскольку между ними нет кода. Если я снова отправлю в вызывающую линию, я получаю сообщение «Can not cast». Как я могу предотвратить деградацию/изменение этого типа объекта?

Многие, многие думают о вашем времени, внимании и любых мыслях или предложениях, которые вы можете предоставить!

ответ

1

Вы должны использовать общий OverLoad JsonSerializer.Deserialize<T>()

var root = serializer.Deserialize<API_Json_Special_Feeds.RootObject>(jsonTextReader); 

В отличие от файлов, генерируемых BinaryFormatter, JSON-файлы, как правило, не включают в себя информацию о C# типа, так что это необходимо для приемной системы, чтобы определить ожидаемый тип.

(Есть расширения для JSON standard, в котором информация C# типа могут быть включены в файл JSON - например Json.NET-х TypeNameHandling. - но по-прежнему необходимо десериализации JSON в соответствующий базовый класс явным образом)

См. Deserialize JSON from a file для другого примера десериализации строго типизированного объекта C# из потока.

+0

Спасибо! Пока это не работает. Я пытаюсь выяснить, где он застрял и отчитается. Нет ошибки - загружает ответ и никогда ничего не возвращает –