官方网站
GitHub下载
[官方文档] Newtonsoft.Json
Json.NET (即,Newtonsoft.Json) 是一种流行的 .NET 高性能 JSON 框架。
System.Windows.Data.IValueConverter 是 WPF 的数据转换器接口,在源数据与目标数据之间做类型转换。
Newtonsoft.Json.JsonConverter 是 Newtonsoft 定义的数据转换抽象类,在序列化和反序列化时做类型或格式转换。
Newtonsoft.Json.Serialization.DefaultContractResolver 是 Newtonsoft 的默认序列化与反序列化解析器,可以创建一个派生它的类,重写DefaultContractResolver() 方法来定义要序列化的属性清单。
string json = JsonConvert.SerializeObject(obj); //序列化
object obj = JsonConvert.DeserializeObject<T>(json); //反序列化
[JsonProperty("y")] //定义序列化别称
public int Y { get; set; }
[JsonConverter(typeof(JsonVector3Converter))] //定义转换器
[JsonConverter(typeof(StringEnumConverter))] //将枚举序列化为字符串
[JsonIgnore] //忽略
一、自定义转换器和解析器
示例:序列化 UnityEngine.Vector3
WPF Vector3 转换器
using System;
using System.Windows.Data;
using System.Globalization;
using Newtonsoft.Json;
using UnityEngine;
using DataEditor.Utils;
namespace DataEditor.Converter
{
/// <summary>
/// WPF Vector3 转换器
/// </summary>
public class Vector3Converter : IValueConverter
{
//缓成上一次正确的对象
private object cacheValue;
//此方法返回的值将绑定到UI上
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Vector3 v = (Vector3)value;
string json = JsonHelper.SerializeVector3(v);
return json;
}
//UI编辑后回传时调用此方法
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
object modifiedValue;
try
{
var settings = new JsonSerializerSettings();
//Json中出现了C#对象中没有的成员时,抛出错误。
settings.MissingMemberHandling = MissingMemberHandling.Error;
Vector3 v = var v = JsonConvert.DeserializeObject(value as string, settings);
modifiedValue = v;
cacheValue = modifiedValue;
}
catch
{
//如果反序列化失败,则用上一次正确的值代替
modifiedValue = cacheValue;
}
return modifiedValue;
}
}
}
Json Vector3 解析器
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace DataEditor.Resolver
{
/// <summary>
/// 参考 https://www.cnblogs.com/yanweidie/p/4605212.html
/// </summary>
public class Vector3ContractResolver : DefaultContractResolver
{
//要序列化的属性清单
string[] props = null;
bool retain;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="props">传入属性数组</param>
/// <param name="retain">true:表示props是需要保留的属性. false:表示props是需要排除的属性</param>
public Vector3ContractResolver(string[] props, bool retain = true)
{
this.props = props;
this.retain = retain;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> list =
base.CreateProperties(type, memberSerialization);
//只保留清单有列出的属性
return list.Where(p => {
if (retain)
{
return props.Contains(p.PropertyName);
}
else
{
return !props.Contains(p.PropertyName);
}
}).ToList();
}
}
}
Json辅助类
using UnityEngine;
using Newtonsoft.Json;
using DataEditor.Resolver;
namespace DataEditor.Utils
{
public sealed class JsonHelper
{
public static string SerializeVector3(Vector3 v)
{
//只序列化Vector3的x,y,z属性
JsonSerializerSettings setting = new JsonSerializerSettings();
setting.ContractResolver = new Vector3ContractResolver(new string[] { "x", "y", "z" }, true);
string json = JsonConvert.SerializeObject(v, setting);
return json;
}
}
}
在Android平台下如果报以下错:
E/Unity: PlatformNotSupportedException: Operation is not supported on this platform.
解决方法: 在Unity的 Project Settings->Player->Other Settings->Api Compatibility Level设置成.NET 4.x
在UWP平台下如果报以下错:
System.Reflection.Emit.DynamicMethod::.ctor
原因:Unity导出IL2CPP过程中剥离掉了Newtonsoft.Json使用到的程序集。
解决方法:
参考: https://blog.csdn.net/abc1329/article/details/126872480
1、将netstandard2.0目录下的Newtonsoft.Json.dll文件拷到Unity工程的Assets/Plugins目录下。
2、在Assets目录下新建link.xml
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
</assembly>
</linker>
参考文献
using System;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
/// <summary>
/// Json 辅助类
/// </summary>
public sealed class JsonHelper
{
public static string ToJson(object obj)
{
string json = "";
try
{
var settings = new JsonSerializerSettings
{
ContractResolver = new FieldContractResolver()
};
//兼容Unity序列化
var receiver = obj as ISerializationCallbackReceiver;
if (receiver != null)
receiver.OnBeforeSerialize();
json = JsonConvert.SerializeObject(obj, settings);
}
catch (Exception ex)
{
Debug.LogErrorFormat("{0}\n{1}", ex.Message, ex.StackTrace);
}
return json;
}
public static object FromJson(string json, Type type)
{
object obj = null;
try
{
obj = JsonConvert.DeserializeObject(json, type);
//兼容Unity序列化
var receiver = obj as ISerializationCallbackReceiver;
if (receiver != null)
receiver.OnAfterDeserialize();
}
catch (Exception ex)
{
Debug.LogErrorFormat("{0}\n{1}", ex.Message, ex.StackTrace);
}
return obj;
}
public static T FromJson<T>(string json)
{
T obj = default(T);
try
{
obj = JsonConvert.DeserializeObject<T>(json);
//兼容Unity序列化
var receiver = obj as ISerializationCallbackReceiver;
if (receiver != null)
receiver.OnAfterDeserialize();
}
catch (Exception ex)
{
Debug.LogErrorFormat("{0}\n{1}", ex.Message, ex.StackTrace);
}
return obj;
}
}
/// <summary>
/// 仅序列化字段(Field)
/// </summary>
public class FieldContractResolver : DefaultContractResolver
{
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
IEnumerable<FieldInfo> enumerable = objectType.GetFields(bindingFlags).Cast<FieldInfo>();
List<MemberInfo> list = new List<MemberInfo>();
foreach (var item in enumerable)
{
//如果字段上添加了忽略特性,直接跳过
var jsonIgnore = item.GetCustomAttributes<JsonIgnoreAttribute>().FirstOrDefault();
if (jsonIgnore != null)
continue;
//如果是public字段
if (item.IsPublic)
{
list.Add(item);
continue;
}
//如果字段上添加了JsonProperty特性
var jsonProperty = item.GetCustomAttributes<JsonPropertyAttribute>().FirstOrDefault();
if (jsonProperty != null)
{
list.Add(item);
}
}
return list;
}
}