JSON.NET使用简单说明
2021-07-08 12:03
标签:comm 类型 intval class override base 类的构造函数 param 二进制 NewtonJson算是比较常用的json解析库了,我的项目中基本都使用该库,因为Unity上也有其相关的库,所以保证了多种项目之间的统一。同时NewtonJson的序列化和反序列化的接口比较简单,相对的功能也比较强大。不过在使用中也不是没有坑的,所以把一些心得记录下,以备日后查询。 序列化和反序列化很简单,调用相关的接口即可。反序列化的时候可以指定泛型参数,直接解析成对应的对象,这个功能比很多轻量级的JSON库要强很多了,省去了我们大量的new对象和赋值的步骤。也可以不指定泛型,解析成的对象可以转换成Dictionary,键值是字符串,value是object。 反序列化的时候,json键值对中的value,如果是整型,统一被转换成long,然后再进行转换,浮点型统一转换成Double,然后转换,string,bool就直接转换了。数组,list可以转换成JArray类型,然后再转换成我们需要的集合类型。 反序列化的时候,JSON.NET是将键值名和对象的成员名对应起来进行赋值的,它只认名称,不管顺序,甚至不管类,比如由以下两个类 同一段JSON可以解析成A也可以解析成B,这在一些项目中存在大量类似的类,或是相同类,处于不同的程序集中非常好用,节省大量的写反序列化的代码。假设Bname3,依然可以解析,并不会因为多了一个成员而无法解析,只是name3没有值而已。 如果我们想指定JSON字符串反序列化的对象,除了使用泛型参数,还可以使用自定义的Converter,继承JsonConverter后,在接受json字符串时,我们可以选择解析成A,或是B。换句话说,对一段JSON字符串指定一个new函数,但new什么,哪怕完全不相关的东西都可以,而json字符串只是new时的参数。 在使用泛型解析的时候,也可以对具体类的构造函数使用[JsonConstructor]特性来指定被反序列化使用的构造函数。在这里Json.Net中它会依次查找合适的构造函数,如果不指定该特性,就会先从默认的构造函数找起。 上面两个构造函数中,JSON.NET会在反序列化时执行第二个带参数的,而且两个参数值分别对应Json字符串中的值,如果形参的名字对应JSON字符串中的key值,而类型不对应,还会抛出异常。形参中没有包括的json的key-value字符串的值,会在构造后再次赋值。比如FValue就不会等于0.001,而是3.14 反序列化时,json.net是先将对象的字符串抽取出来,然后new出对象,并将这部分的json字符串传递给构造函数进行赋值,如果是默认构造函数,则会在new出后,进行赋值。这里一个问题是,如果使用了[JsonConstructor]指定了构造函数,而该函数是接受参数的,那么再new之后就不会再次赋值了,如果构造函数内没有对这个参数进行赋值,那这个值就丢失了。这个在我们使用时,就因为这个原因,造成总是丢失数据 反序列化多态对象时,因为可能具体的类的成员比泛型参数来的多,想要正确反序列化的话,需要在序列化时,在JSON字符串中增加有效的类型信息。要继承SerializeBinder,该类的两个接口可以将类型转换成字符串,添加到json字符串中,反序列化时,通过拿到类型的字符串,使用反射来new出具体对象。 如果TypeNameSerializationBinder的BindToName函数中对输出参数assemblyName指定了“程序集”,输出的json就是第二段的样子,而在BindToType时的assemblyName的参数值就会时“程序集”字样,依靠这些信息我们就能使用反射来正确的生成子类对象 看文档Json.net还支持直接反序列化二进制的json文件,缩小文件体积,加快速度,具体使用下回再补了 使用下来后,我觉得在json反序列化时可以增加根据实例对象进行反序列化,先new出具体对象,再反序列化,这样反序列化时就可以明确有哪些成员。 JSON.NET使用简单说明 标签:comm 类型 intval class override base 类的构造函数 param 二进制 原文地址:http://www.cnblogs.com/indie-developer/p/7097767.html序列化和反序列化
var data = new JsonData() {IntValue = 1000, FValue = 3.14f, IsTrue = true, Text = "Hello World"};
//序列化 json = "{\"IntValue\":1000,\"Text\":\"Hello World\",\"IsTrue\":true,\"FValue\":3.14}"
var json = JsonConvert.SerializeObject(data);
//反序列化
data = JsonConvert.DeserializeObjectJsonData>(json);
//不指定泛型的反序列化
var dict = JsonConvert.DeserializeObjectDictionary
var dict = JsonConvert.DeserializeObject
class JsonData
{
public int IntValue;
public string Text;
public bool IsTrue;
public float FValue;
public int[] array;
public Listint> list;
}
class JsonDataB
{
public bool IsTrue;
public int IntValue;
public float FValue;
public int[] array;
public Listint> list;
public string Text;
}
var datab = JsonConvert.DeserializeObject
指定反序列化的对象
class DataConvert : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var data = new JsonDataB();
while(reader.Read())
{
if(reader.Value.ToString() == "IntValue")
{
data.IntValue = reader.ReadAsInt32().Value;
}
}
return data;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
class JsonData
{
public int IntValue;
public string Text;
public bool IsTrue;
public float FValue;
public int[] array;
public Listint> list;
public JsonData()
{
}
[JsonConstructor]
public JsonData(int intvalue, string text, bool istrue)
{
IntValue = intvalue * 2; //改变
Text = "We can do every thing we want here";
FValue = 0.001f; //不改变
//istrue丢失
}
}
data = JsonConvert.DeserializeObject
多态反序列化
public class TypeNameSerializationBinder : ISerializationBinder
{
public TypeNameSerializationBinder()
{
}
///
BSON
改进