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