JSON意外结束

时间:2017-03-29 13:55:32

标签: c# json

我遇到了一个例外情况,我似乎无法找到很多关于网络的信息。

意外结束。行#,位置######

一些细节,这是在Windows 6.5.3,即移动.NET CE框架上运行的。我正在解析来自Web服务调用的响应。我已经验证了响应是正确的JSON格式,但我知道响应非常非常大。

我无法弄明白,这就是为什么我得到了这个问题。这是我的解析代码(是的,我们总是得到复杂对象的列表)

List<T> objList = new List<T>();
using (StreamReader sr = new StreamReader(responseStream))
{
    using (JsonTextReader jr = new JsonTextReader(sr))
    {             
        JsonSerializer ser = new JsonSerializer();          
        JObject jo = ser.Deserialize(jr) as JObject;  //<---- This line throws the exception
        if (jo != null)
        {                      
            List<JToken> jResults = jo[name + "Result"].Children().ToList();
            foreach (JToken jObjResult in jResults)
            {
                T obj = JsonConvert.DeserializeObject<T>(jObjResult.ToString());
                objList.Add(obj);
            }
        }
    }
}
return objList;

任何能够对此有所了解的人都可以。谢谢。

更新:添加完全异常文本

Message: "Unexpected end. Line 1, position 1594143."
StackTrace:
       at Newtonsoft.Json.JsonTextReader.ParseValue(Char currentChar)
       at Newtonsoft.Json.JsonTextReader.ReadInternal()
       at Newtonsoft.Json.JsonTextReader.Read()
       at Newtonsoft.Json.JsonWriter.WriteToken(JsonReader reader, Int32 initialDepth)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateJObject(JsonReader reader)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract)
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
       at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader)
       at MY CODE HIDDEN HERE

注意:确切位置有时会有所不同,但似乎总是大于65536

1 个答案:

答案 0 :(得分:0)

确定。我弄清楚是什么导致了这个问题,但它根本不容易重现,因为它与连接速度有关。从字面上看,响应流能够提供数据的速度。

修改后的代码

using (StreamReader sr = new StreamReader(responseStream))
{
    using (JsonTextReader jr = new JsonTextReader(sr))
    {
        while (jr.Read())
            if (jr.TokenType == JsonToken.StartArray)
                break;
        jr.Read();

        JsonSerializer Jser = new JsonSerializer();
        while (!sr.EndOfStream && jr.TokenType != JsonToken.EndArray)
        {
            if(jr.TokenType == JsonToken.StartObject)
            {
                T tobj = Jser.Deserialize<T>(jr);
                objList.Add(tobj);
            }
            //consume the EndObject tag
            if (jr.TokenType == JsonToken.EndObject)
                jr.Read();
            //Deliberately slow down the process, On purpose, otherwise we will overrun the stream itself and throw an error
            Thread.Sleep(1); //<=== VERY IMPORTANT LINE
        }
    }
}

解释

我通过检查故障时的流位置找到了这个。我注意到它一直在变化,我终于发现这个变化是基于我花了多长时间在调试模式下暂停查看细节的过程。我花的时间越长,读数就会越远。所以我改变了它,一次手动推进一个对象(这也花了一些时间,但我弄清楚了令牌顺序是什么)。在一个非常短的线程睡眠中添加。而且效果很好。

总而言之。通过慢速连接从响应流直接加载JSON时,您实际上可以比响应流提供的数据更快地序列化数据。在这种情况下,它将报告“意外结束”。