Newtonsoft.Json

作者:追风剑情 发布于:2021-9-7 9:43 分类:C#

官方网站
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> 
参考文献
[Unity手册] ManagedCodeStripping
[微软文档] Add packages from NuGet to a Unity project




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;
    }
}

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号