FallbackJsonPropertyResolver.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using Newtonsoft.Json;
  2. using Newtonsoft.Json.Serialization;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Reflection;
  7. namespace Masuit.Tools.Systems;
  8. /// <summary>
  9. /// 多别名属性的解释器
  10. /// </summary>
  11. public class FallbackJsonPropertyResolver : CamelCasePropertyNamesContractResolver
  12. {
  13. /// <summary>
  14. /// 序列化时忽略的字段集
  15. /// </summary>
  16. protected readonly Dictionary<Type, HashSet<string>> SerializeIgnores = new();
  17. /// <summary>
  18. /// 反序列化时忽略的字段集
  19. /// </summary>
  20. protected readonly Dictionary<Type, HashSet<string>> DeserializeIgnores = new();
  21. /// <summary>
  22. /// 序列化时忽略
  23. /// </summary>
  24. /// <param name="type">类型</param>
  25. /// <param name="propertyName">属性名</param>
  26. /// <returns></returns>
  27. public FallbackJsonPropertyResolver SerializeIgnore(Type type, params string[] propertyName)
  28. {
  29. if (!SerializeIgnores.ContainsKey(type)) SerializeIgnores[type] = new HashSet<string>();
  30. foreach (var prop in propertyName)
  31. {
  32. SerializeIgnores[type].Add(prop);
  33. }
  34. return this;
  35. }
  36. /// <summary>
  37. /// 反序列化时忽略
  38. /// </summary>
  39. /// <param name="type">类型</param>
  40. /// <param name="propertyName">属性名</param>
  41. /// <returns></returns>
  42. public FallbackJsonPropertyResolver DeserializeIgnore(Type type, params string[] propertyName)
  43. {
  44. if (!DeserializeIgnores.ContainsKey(type)) DeserializeIgnores[type] = new HashSet<string>();
  45. foreach (var prop in propertyName)
  46. {
  47. DeserializeIgnores[type].Add(prop);
  48. }
  49. return this;
  50. }
  51. public bool IsSerializeIgnored(Type type, string propertyName)
  52. {
  53. if (!SerializeIgnores.ContainsKey(type)) return false;
  54. if (SerializeIgnores[type].Count == 0) return true;
  55. return SerializeIgnores[type].Contains(propertyName, StringComparer.CurrentCultureIgnoreCase);
  56. }
  57. public bool IsDeserializeIgnored(Type type, string propertyName)
  58. {
  59. if (!DeserializeIgnores.ContainsKey(type)) return false;
  60. if (DeserializeIgnores[type].Count == 0) return true;
  61. return DeserializeIgnores[type].Contains(propertyName, StringComparer.CurrentCultureIgnoreCase);
  62. }
  63. protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
  64. {
  65. var typeMembers = GetSerializableMembers(type).DistinctBy(m => m.Name);
  66. var properties = new List<JsonProperty>();
  67. foreach (var member in typeMembers)
  68. {
  69. var property = CreateProperty(member, memberSerialization);
  70. if (IsSerializeIgnored(property.DeclaringType, property.PropertyName))
  71. {
  72. property.ShouldSerialize = _ => false;
  73. }
  74. if (IsDeserializeIgnored(property.DeclaringType, property.PropertyName))
  75. {
  76. property.ShouldDeserialize = _ => false;
  77. }
  78. properties.RemoveAll(p => p.PropertyName == property.PropertyName);
  79. properties.Add(property);
  80. var fallbackAttribute = member.GetCustomAttribute<FallbackJsonProperty>();
  81. if (fallbackAttribute == null)
  82. {
  83. continue;
  84. }
  85. property.PropertyName = fallbackAttribute.PreferredName;
  86. foreach (var alternateName in fallbackAttribute.FallbackReadNames)
  87. {
  88. properties.RemoveAll(p => p.PropertyName == alternateName);
  89. var fallbackProperty = CreateProperty(member, memberSerialization);
  90. fallbackProperty.PropertyName = alternateName;
  91. fallbackProperty.ShouldSerialize = _ => false;
  92. fallbackProperty.ShouldDeserialize = _ => true;
  93. properties.Add(fallbackProperty);
  94. }
  95. }
  96. return properties;
  97. }
  98. }