using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Masuit.Tools.Systems; /// /// 多别名属性的解释器 /// public class FallbackJsonPropertyResolver : CamelCasePropertyNamesContractResolver { /// /// 序列化时忽略的字段集 /// protected readonly Dictionary> SerializeIgnores = new(); /// /// 反序列化时忽略的字段集 /// protected readonly Dictionary> DeserializeIgnores = new(); /// /// 序列化时忽略 /// /// 类型 /// 属性名 /// public FallbackJsonPropertyResolver SerializeIgnore(Type type, params string[] propertyName) { if (!SerializeIgnores.ContainsKey(type)) SerializeIgnores[type] = new HashSet(); foreach (var prop in propertyName) { SerializeIgnores[type].Add(prop); } return this; } /// /// 反序列化时忽略 /// /// 类型 /// 属性名 /// public FallbackJsonPropertyResolver DeserializeIgnore(Type type, params string[] propertyName) { if (!DeserializeIgnores.ContainsKey(type)) DeserializeIgnores[type] = new HashSet(); foreach (var prop in propertyName) { DeserializeIgnores[type].Add(prop); } return this; } public bool IsSerializeIgnored(Type type, string propertyName) { if (!SerializeIgnores.ContainsKey(type)) return false; if (SerializeIgnores[type].Count == 0) return true; return SerializeIgnores[type].Contains(propertyName, StringComparer.CurrentCultureIgnoreCase); } public bool IsDeserializeIgnored(Type type, string propertyName) { if (!DeserializeIgnores.ContainsKey(type)) return false; if (DeserializeIgnores[type].Count == 0) return true; return DeserializeIgnores[type].Contains(propertyName, StringComparer.CurrentCultureIgnoreCase); } protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { var typeMembers = GetSerializableMembers(type).DistinctBy(m => m.Name); var properties = new List(); foreach (var member in typeMembers) { var property = CreateProperty(member, memberSerialization); if (IsSerializeIgnored(property.DeclaringType, property.PropertyName)) { property.ShouldSerialize = _ => false; } if (IsDeserializeIgnored(property.DeclaringType, property.PropertyName)) { property.ShouldDeserialize = _ => false; } properties.RemoveAll(p => p.PropertyName == property.PropertyName); properties.Add(property); var fallbackAttribute = member.GetCustomAttribute(); if (fallbackAttribute == null) { continue; } property.PropertyName = fallbackAttribute.PreferredName; foreach (var alternateName in fallbackAttribute.FallbackReadNames) { properties.RemoveAll(p => p.PropertyName == alternateName); var fallbackProperty = CreateProperty(member, memberSerialization); fallbackProperty.PropertyName = alternateName; fallbackProperty.ShouldSerialize = _ => false; fallbackProperty.ShouldDeserialize = _ => true; properties.Add(fallbackProperty); } } return properties; } }