【问题标题】:NewtonSoft Json Invalid Cast ExceptionNewtonSoft Json 无效转换异常
【发布时间】:2016-09-10 03:31:09
【问题描述】:

这与我的问题 HTTPClient Buffer Exceeded 2G; Cannot write more bytes to the buffer 相关,但差异很大,以至于 IMO 需要一个单独的问题。

在另一个问题中,我试图弄清楚如何处理破坏 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。我无法调试它,因为两者之间没有代码。如果我在调用行中再次投射,我会收到“无法投射”错误。如何防止此对象类型的降级/更改?

很多很多人都在考虑您的时间、考虑以及您可以提供的任何想法或建议!

【问题讨论】:

    标签: c# json json.net


    【解决方案1】:

    你需要使用泛型重载JsonSerializer.Deserialize&lt;T&gt;()

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

    BinaryFormatter生成的文件不同,JSON文件一般不包含c#类型信息,所以接收系统需要指定期望的类型。

    JSON standard 有扩展,其中 c# 类型信息可以包含在 JSON 文件中——例如 Json.NET 的 TypeNameHandling——但仍然需要将 JSON 反序列化为适当的显式基类.)

    有关从流中反序列化强类型 c# 对象的另一个示例,请参阅 Deserialize JSON from a file

    【讨论】:

    • 谢谢!到目前为止,这行不通。我试图找出它卡在哪里并会报告。没有错误 - 加载响应并且从不返回任何内容
    猜你喜欢
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    相关资源
    最近更新 更多