Răsfoiți Sursa

Feat System.Text.Json版本序列化反序列化拓展方法支持,添加根据键排序Resolver

NENE 10 luni în urmă
părinte
comite
70425ccd7b

+ 77 - 1
Masuit.Tools.Abstractions/Extensions/BaseType/ObjectExtensions.cs

@@ -16,6 +16,16 @@ using JsonSerializer = System.Text.Json.JsonSerializer;
 
 #endif
 
+#if NET5_0_OR_GREATER
+
+using System.Text.Json;
+using Masuit.Tools.Systems;
+using JsonSerializer = System.Text.Json.JsonSerializer;
+using System.Text.Encodings.Web;
+using System.Text.Json.Serialization;
+
+#endif
+
 namespace Masuit.Tools;
 
 /// <summary>
@@ -25,6 +35,25 @@ public static class ObjectExtensions
 {
     private static readonly MethodInfo CloneMethod = typeof(object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance);
 
+#if NET5_0_OR_GREATER
+    /// <summary>
+    /// System.Text.Json 默认配置 支持中文
+    /// </summary>
+    private static readonly JsonSerializerOptions DefaultJsonSerializerOptions = new()
+    {
+        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+    };
+
+    /// <summary>
+    /// System.Text.Json 支持中文/忽略null值
+    /// </summary>
+    private static readonly JsonSerializerOptions IgnoreNullJsonSerializerOptions = new()
+    {
+        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
+    };
+
+#endif
     /// <summary>
     /// 是否是基本数据类型
     /// </summary>
@@ -118,7 +147,9 @@ public static class ObjectExtensions
     /// <returns></returns>
     public static object DeepClone(this object originalObject, bool useJson = false)
     {
-        return useJson ? InternalJsonCopy(originalObject) : InternalCopy(originalObject, new Dictionary<object, object>(new ReferenceEqualityComparer()));
+        return useJson
+            ? InternalJsonCopy(originalObject)
+            : InternalCopy(originalObject, new Dictionary<object, object>(new ReferenceEqualityComparer()));
     }
 
     /// <summary>
@@ -270,6 +301,51 @@ public static class ObjectExtensions
         return string.IsNullOrEmpty(json) ? default : JsonConvert.DeserializeObject<T>(json, setting);
     }
 
+    #region System.Text.Json
+
+    #if NET5_0_OR_GREATER
+    
+    /// <summary>
+    /// 转换成json字符串
+    /// </summary>
+    /// <param name="obj"></param>
+    /// <param name="setting"></param>
+    /// <returns></returns>
+    public static string ToJson(this object obj, JsonSerializerOptions setting = null)
+    {
+        if (obj == null) return string.Empty;
+        setting ??= DefaultJsonSerializerOptions;
+        return JsonSerializer.Serialize(obj,setting);
+    }
+    
+    /// <summary>
+    /// 转换成json字符串并忽略Null值
+    /// </summary>
+    /// <param name="obj"></param>
+    /// <param name="setting"></param>
+    /// <returns></returns>
+    public static string ToJsonIgnoreNull(this object obj)
+    {
+        if (obj == null) return string.Empty;
+        return JsonSerializer.Serialize(obj,IgnoreNullJsonSerializerOptions);
+    }
+
+    /// <summary>
+    /// 反序列化
+    /// </summary>
+    /// <param name="json"></param>
+    /// <param name="settings"></param>
+    /// <returns></returns>
+    public static T ToObject<T>(this string json, JsonSerializerOptions settings = null)
+    {
+        return string.IsNullOrEmpty(json) ? default : JsonSerializer.Deserialize<T>(json, settings);
+    }
+
+    #endif
+
+    #endregion
+
+
     /// <summary>
     /// 链式操作
     /// </summary>

+ 24 - 0
Masuit.Tools.Abstractions/Systems/SerializeSortByNameResolver.cs

@@ -0,0 +1,24 @@
+#if NET5_0_OR_GREATER
+using System;
+using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Serialization.Metadata;
+
+namespace Masuit.Tools.Systems;
+
+public class SerializeSortByNameResolver : DefaultJsonTypeInfoResolver
+{
+	public override JsonTypeInfo GetTypeInfo(Type t, JsonSerializerOptions o)
+	{
+		var jti = base.GetTypeInfo(t, o);
+        int order = 1;
+
+        foreach (var property in jti.Properties.OrderBy(p => p.Name))
+        {
+            property.Order = order++;
+        }
+        
+        return jti;
+	}
+}
+#endif

+ 93 - 0
Test/Masuit.Tools.Core.Test/AspNetCore/ObjectExtensionTests.cs

@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Http;
+using System.Text.Encodings.Web;
+using System.Text.Json;
+using System.Threading.Tasks;
+using Masuit.Tools.Systems;
+using Xunit;
+
+namespace Masuit.Tools.Core.Test.AspNetCore
+{
+    public class ObjectExtensionTests : TestBase
+    {
+        [Fact]
+        public void ToJsonTest()
+        {
+            var obj = new
+            {
+                Id = 1,
+                name = "van",
+                addressInfo = new
+                {
+                    street = "123 Main St",
+                    city = "zcvz",
+                },
+                remarks = new List<string> { "Deep  Dark  Fantastic", "爱玩游戏♂" },
+            };
+
+            var json = obj.ToJson();
+
+            Assert.Equal(
+                "{\"Id\":1,\"name\":\"van\",\"addressInfo\":{\"street\":\"123 Main St\",\"city\":\"zcvz\"},\"remarks\":[\"Deep  Dark  Fantastic\",\"爱玩游戏\u2642\"]}",
+                json);
+        }
+
+        [Fact]
+        public void ToJsonIgnoreNullTest()
+        {
+            var obj = new People
+            {
+                Name = "van",
+                Age = 52,
+            };
+
+            var json = obj.ToJsonIgnoreNull();
+
+            Assert.Equal(
+                "{\"Name\":\"van\",\"Age\":52}",
+                json);
+        }
+
+        [Fact]
+        public void FromObjectTest()
+        {
+            var json = "{\"Name\":\"van\",\"Age\":52}";
+
+            var obj = json.ToObject<People>();
+
+            Assert.Equal(
+                "van",
+                obj.Name);
+        }
+
+
+        [Fact]
+        public void SerializeSortByNameTest()
+        {
+            var obj = new People
+            {
+                Name = "van",
+                Age = 52,
+            };
+
+            var json = obj.ToJson(new JsonSerializerOptions
+            {
+                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+                TypeInfoResolver = new SerializeSortByNameResolver()
+            });
+
+            Assert.Equal(
+                "{\"Age\":52,\"Name\":\"van\"}",
+                json);
+        }
+
+
+        private class People
+        {
+            public string Name { get; set; }
+            public int Age { get; set; }
+        }
+    }
+}