126 lines
5.3 KiB
C#
126 lines
5.3 KiB
C#
using AyCode.Core.Interfaces;
|
|
using MessagePack;
|
|
using MessagePack.Resolvers;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using Newtonsoft.Json.Serialization;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace AyCode.Core.Extensions;
|
|
|
|
public static class SerializeObjectExtensions
|
|
{
|
|
public static readonly JsonSerializerSettings Options = new()
|
|
{
|
|
//TypeNameHandling = TypeNameHandling.All,
|
|
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
|
NullValueHandling = NullValueHandling.Ignore,
|
|
|
|
////System.Text.Json
|
|
//ReferenceHandler.Preserve
|
|
//ReferenceHandler.IgnoreCycles
|
|
};
|
|
|
|
|
|
public static string ToJson<T>(this T source, JsonSerializerSettings? options = null) => JsonConvert.SerializeObject(source, options ?? Options);
|
|
public static string ToJson<T>(this IQueryable<T> source, JsonSerializerSettings? options = null) where T : class, IAcSerializableToJson => JsonConvert.SerializeObject(source, options ?? Options);
|
|
public static string ToJson<T>(this IEnumerable<T> source, JsonSerializerSettings? options = null) where T : class, IAcSerializableToJson => JsonConvert.SerializeObject(source, options ?? Options);
|
|
|
|
public static T? JsonTo<T>(this string json, JsonSerializerSettings? options = null)
|
|
{
|
|
if (json.StartsWith("\"") && json.EndsWith("\"")) json = Regex.Unescape(json).TrimStart('"').TrimEnd('"');
|
|
|
|
return JsonConvert.DeserializeObject<T>(json, options ?? Options);
|
|
}
|
|
|
|
public static object? JsonTo(this string json, Type toType, JsonSerializerSettings? options = null)
|
|
{
|
|
if (json.StartsWith("\"") && json.EndsWith("\"")) json = Regex.Unescape(json).TrimStart('"').TrimEnd('"');
|
|
|
|
return JsonConvert.DeserializeObject(json, toType, options ?? Options);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Using JSON
|
|
/// </summary>
|
|
/// <typeparam name="TDestination"></typeparam>
|
|
/// <param name="src"></param>
|
|
/// <param name="options"></param>
|
|
/// <returns></returns>
|
|
[return: NotNullIfNotNull(nameof(src))]
|
|
public static TDestination? CloneTo<TDestination>(this object? src, JsonSerializerSettings? options = null) where TDestination : class => src?.ToJson(options).JsonTo<TDestination>(options);
|
|
|
|
//public static string ToJson(this Expression source) => JsonConvert.SerializeObject(source, Options);
|
|
|
|
public static byte[] ToMessagePack(this object message) => MessagePackSerializer.Serialize(message);
|
|
public static byte[] ToMessagePack(this object message, MessagePackSerializerOptions options) => MessagePackSerializer.Serialize(message, options);
|
|
|
|
public static T MessagePackTo<T>(this byte[] message) => MessagePackSerializer.Deserialize<T>(message);
|
|
public static T MessagePackTo<T>(this byte[] message, MessagePackSerializerOptions options) => MessagePackSerializer.Deserialize<T>(message, options);
|
|
}
|
|
|
|
public class IgnoreAndRenamePropertySerializerContractResolver : DefaultContractResolver
|
|
{
|
|
private readonly Dictionary<Type, HashSet<string>> _ignores = new();
|
|
private readonly Dictionary<Type, HashSet<string>> _includes = new();
|
|
private readonly Dictionary<Type, Dictionary<string, string>> _renames = new();
|
|
|
|
public void IgnoreProperty(Type type, params string[] jsonPropertyNames)
|
|
{
|
|
if (!_ignores.ContainsKey(type)) _ignores[type] = [];
|
|
|
|
foreach (var prop in jsonPropertyNames) _ignores[type].Add(prop);
|
|
}
|
|
|
|
public void IncludesProperty(Type type, params string[] jsonPropertyNames)
|
|
{
|
|
if (!_includes.ContainsKey(type)) _includes[type] = [];
|
|
|
|
foreach (var prop in jsonPropertyNames) _includes[type].Add(prop);
|
|
}
|
|
|
|
public void RenameProperty(Type type, string propertyName, string newJsonPropertyName)
|
|
{
|
|
if (!_renames.ContainsKey(type)) _renames[type] = new Dictionary<string, string>();
|
|
|
|
_renames[type][propertyName] = newJsonPropertyName;
|
|
}
|
|
|
|
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
|
{
|
|
var property = base.CreateProperty(member, memberSerialization);
|
|
|
|
if (IsIgnored(property.DeclaringType, property.PropertyName) || !IsIncluded(property.DeclaringType, property.PropertyName))
|
|
{
|
|
property.ShouldSerialize = i => false;
|
|
property.Ignored = true;
|
|
}
|
|
|
|
if (IsRenamed(property.DeclaringType, property.PropertyName, out var newJsonPropertyName))
|
|
property.PropertyName = newJsonPropertyName;
|
|
|
|
return property;
|
|
}
|
|
|
|
private bool IsIgnored(Type type, string jsonPropertyName)
|
|
{
|
|
return _ignores.ContainsKey(type) && _ignores[type].Contains(jsonPropertyName);
|
|
}
|
|
private bool IsIncluded(Type type, string jsonPropertyName)
|
|
{
|
|
return _includes.Count == 0 || (_includes.ContainsKey(type) && _includes[type].Contains(jsonPropertyName));
|
|
}
|
|
|
|
private bool IsRenamed(Type type, string jsonPropertyName, out string? newJsonPropertyName)
|
|
{
|
|
if (_renames.TryGetValue(type, out var renames) && renames.TryGetValue(jsonPropertyName, out newJsonPropertyName)) return true;
|
|
|
|
newJsonPropertyName = null;
|
|
return false;
|
|
}
|
|
}
|