using IRaCIS.Core.Infrastructure.NewtonsoftJson; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Reflection.Metadata; namespace IRaCIS.Core.API { /// /// LowerCamelCaseJsonAttribute 可以设置类小写返回给前端 /// public class NullToEmptyStringResolver : DefaultContractResolver { protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { // 检查类是否有 LowerCamelCaseJsonAttribute 标记 有的话,属性名小写 if (type.GetCustomAttribute() != null) { base.NamingStrategy = new LowerCamelCaseNamingStrategy(); } else { base.NamingStrategy = null; } IList properties = base.CreateProperties(type, memberSerialization); var list = type.GetProperties() .Select(p => { var jp = base.CreateProperty(p, memberSerialization); jp.ValueProvider = new NullToEmptyStringValueProvider(p); return jp; }).ToList(); var uu = list.Select(t => t.PropertyName).ToList(); //获取复杂对象属性 properties = properties.TakeWhile(t => !uu.Contains(t.PropertyName)).ToList(); list.AddRange(properties); return list; } } public class NullToEmptyStringValueProvider : IValueProvider { PropertyInfo _memberInfo; private readonly bool _isNullable; public NullToEmptyStringValueProvider(PropertyInfo memberInfo) { _memberInfo = memberInfo; } // DTO → JSON 返回前端的时候 处理null 变为"" 方便前端判断 public object GetValue(object target) { var result = _memberInfo.GetValue(target); // 检查类型是否为string或string? if (_memberInfo.PropertyType == typeof(string) && result == null) { #region 返回的时候处理 string string? null 为"" 不区分处理 //// 如果是string?类型,返回null 可以做到,但是得反射,因为 string string? 是编译层区分的 //var isNullable1 = _memberInfo.CustomAttributes // .Any(a => a.AttributeType.Name == "NullableAttribute"); ////var isNullable2 = _memberInfo.CustomAttributes //// .Any(a => a.AttributeType.FullName == "System.Runtime.CompilerServices.NullableAttribute"); //if (isNullable1) //{ // return result; //} #endregion // 如果是string类型,返回空字符串 return string.Empty; } return result; } //影响 模型绑定时接收前端的值,同时影响 正常 JSON 序列化 public void SetValue(object target, object value) { _memberInfo.SetValue(target, value); #region 前端针对 string 类型的变量,如果传递null 会报错必传 //if (_memberInfo.PropertyType == typeof(string)) //{ // _memberInfo.SetValue(target, value == null ? string.Empty : value); //} //else //{ // _memberInfo.SetValue(target, value); //} #endregion #region 处理模型验证区分 string string? //////接收模型的时候 定义的明明是string 但是上面也有该属性,判断不准的 比如阅片跟踪列表查询 //var isNullable1 = _memberInfo.CustomAttributes.Any(a => a.AttributeType.Name == "NullableAttribute"); ////不影响 string? 传递null 变为"" //if (_memberInfo.PropertyType == typeof(string) && isNullable1 == false) //{ // //如果不处理 前段传递null string不会接收,说前段没传递会验证报错 // _memberInfo.SetValue(target, value == null ? string.Empty : value); //} //else //{ // _memberInfo.SetValue(target, value); //} #endregion } } }