2017-10-12 270 views
0

我想从数据库中读取作为字符串存储的JSON数据,并且需要以不同方式转换数据。我看到JSON.NET在内部从JsonTextReader引发错误。我试图通过直接使用下面的代码来重现错误。这段代码有什么问题?使用JsonTextReader读取JSON会引发错误

var rs = new Newtonsoft.Json.JsonTextReader(new System.IO.StringReader("{'1':'2'}")); 
rs.ReadAsString(); 

它抛出一个错误:

Unexpected character encountered while parsing value: {. Path '', line 1, position 1.

回答

2

由于你使用的是正确JsonTextReader得到一个错误。

JsonTextReader类将JSON字符串视为一系列“令牌”,它们一次只能读取一个。可能的标记在本JsonToken枚举中定义,包括StartObjectStartArrayPropertyNameStringIntegerBooleanNullEndObjectEndArray仅举几例。

当您致电ReadAsString时,会将读者推进到下一个标记并尝试将该标记解释为字符串。在你的JSON中,第一个标记不是一个字符串;它是StartObject(对应于左大括号{)。 ReadAsString不期待这个,所以它会抛出一个错误。

ReadAs...方法实际上只在您已经事先知道读者遇到的下一个令牌是特定类型(例如字符串)的情况下才有用。如果您事先不知道JSON结构并希望使用JsonTextReader来扫描它,则可以通过在循环中调用Read方法直到它返回false来完成。每个Read调用将读取器推进到下一个标记并设置TokenTypeValue属性。然后您可以检查TokenType以确定如何处理Value

下面是一个简单的示例,它使用JsonTextReader循环遍历JSON,并在每个步骤中转储出TokenTypeValue。这应该给你一个好主意,读者如何看待您的JSON:

JsonTextReader rs = new JsonTextReader(new StringReader("{'1':'2'}")); 

Console.WriteLine("TokenType  Value"); 
Console.WriteLine("------------ ------"); 
while (rs.Read()) 
{ 
    Console.WriteLine(string.Format("{0,-12} {1}", 
     rs.TokenType.ToString(), 
     rs.Value != null ? rs.Value.ToString() : "(null)")); 
} 

小提琴:https://dotnetfiddle.net/nxWd1X

这里是输出:

TokenType  Value 
------------ ------ 
StartObject (null) 
PropertyName 1 
String  2 
EndObject  (null) 

牢记JsonTextReader是一个用于解析JSON的相当低级别的API,并且对于除最简单的JSON结构之外的所有应用程序都可能变得很难使用。如果您的JSON具有众所周知的结构,则可以使用JsonConvert.DeserializeObject<T>定义匹配的类(或一组类)并将其反序列化为该类。例如:

public class RootObject 
{ 
    [JsonProperty("1")] 
    public string One { get; set; } 
} 

var root = JsonConvert.DeserializeObject<RootObject>("{'1':'2'}"); 

Console.WriteLine(root.One); // 2 

另外,如果你的JSON结构是动态的或不为人熟知,您可以使用LINQ-to-JSON API(JObjects)来代替。例如:

var obj = JObject.Parse("{'1':'2'}"); 
foreach (JProperty prop in obj.Properties()) 
{ 
    Console.WriteLine(prop.Name + ": " + prop.Value); // 1: 2 
} 
+0

谢谢。我已经知道了。我的意图是读完整的JSON字符串并反序列化它。我必须为一个接口实现一个通用'任务获取(key)'方法,其中实际实现需要从以JSON形式存储数据的数据存储中获取数据,主要是将序列化对象视为JSON格式,但有时必须返回读取字符串以及,其中T是字符串,我已经使用了'JSONConvert.DeserilaizeObject (字符串)'为此,这是我得到这个错误。 –

相关问题