我试图逐步解析JSON,即基于条件.
下面是我的json消息,我目前正在使用JavaScriptSerializer来反序列化消息.
string json = @"{"id":2,
"method":"add",
"params":
{"object":
{"name":"test"
"id":"1"},
"position":"1"}
}";
JavaScriptSerializer js = new JavaScriptSerializer();
Message m = js.Deserialize<Message>(json);
Run Code Online (Sandbox Code Playgroud)
消息类如下所示:
public class Message
{
public string id { get; set; }
public string method { get; set; }
public Params @params { get; set; }
public string position { get; set; }
}
public class Params
{
public string name { get; set; }
public string id{ get; set;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码解析消息没有问题.但它会立即解析整个JSON.我希望它仅在"method"参数的值为"add"时才进行解析.如果它不是"添加",那么我不希望它继续解析其余的消息.有没有办法根据C#中的条件进行增量解析?(环境:VS 2008与.Net 3.5)
Dav*_*ter 14
我不得不承认我对JavaScriptSerializer并不熟悉,但是如果你愿意使用JSON.net,它的JsonReader行为就像是一个DataReader.
using(var jsonReader = new JsonTextReader(myTextReader)){
while(jsonReader.Read()){
//evaluate the current node and whether it's the name you want
if(jsonReader.TokenType.PropertyName=="add"){
//do what you want
} else {
//break out of loop.
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我用来解析,加载和创建非常大的JSON文件的通用和简单方法.该代码现在使用了非常标准的JSON.Net库.不幸的是,文档不是很清楚如何做到这一点,但也不是很难弄清楚.
下面的代码假定您要将大量对象要序列化为JSON数组的情况,反之亦然.我们希望支持非常大的文件,这些文件的大小仅受存储设备(不是内存)的限制.因此,在序列化时,该方法需要IEnumerable<T>并且在反序列化时返回相同的内容.这样您就可以处理整个文件而不受内存的限制.
我已经将这段代码用于几GB的文件大小,并且性能合理.
//Serialize sequence of objects as JSON array in to a specified file
public static void SerializeSequenceToJson<T>(this IEnumerable<T> sequence, string fileName)
{
using (var fileStream = File.CreateText(fileName))
SerializeSequenceToJson(sequence, fileStream);
}
//Deserialize specified file in to IEnumerable assuming it has array of JSON objects
public static IEnumerable<T> DeserializeSequenceFromJson<T>(string fileName)
{
using (var fileStream = File.OpenText(fileName))
foreach (var responseJson in DeserializeSequenceFromJson<T>(fileStream))
yield return responseJson;
}
//Utility methods to operate on streams instead of file
public static void SerializeSequenceToJson<T>(this IEnumerable<T> sequence, TextWriter writeStream, Action<T, long> progress = null)
{
using (var writer = new JsonTextWriter(writeStream))
{
var serializer = new JsonSerializer();
writer.WriteStartArray();
long index = 0;
foreach (var item in sequence)
{
if (progress != null)
progress(item, index++);
serializer.Serialize(writer, item);
}
writer.WriteEnd();
}
}
public static IEnumerable<T> DeserializeSequenceFromJson<T>(TextReader readerStream)
{
using (var reader = new JsonTextReader(readerStream))
{
var serializer = new JsonSerializer();
if (!reader.Read() || reader.TokenType != JsonToken.StartArray)
throw new Exception("Expected start of array in the deserialized json string");
while (reader.Read())
{
if (reader.TokenType == JsonToken.EndArray) break;
var item = serializer.Deserialize<T>(reader);
yield return item;
}
}
}
Run Code Online (Sandbox Code Playgroud)