144 lines
4.5 KiB
C#
144 lines
4.5 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// LowerCamelCaseJsonAttribute 可以设置类小写返回给前端
|
||
/// </summary>
|
||
public class NullToEmptyStringResolver : DefaultContractResolver
|
||
{
|
||
|
||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||
{
|
||
// 检查类是否有 LowerCamelCaseJsonAttribute 标记 有的话,属性名小写
|
||
if (type.GetCustomAttribute<LowerCamelCaseJsonAttribute>() != null)
|
||
{
|
||
base.NamingStrategy = new LowerCamelCaseNamingStrategy();
|
||
}
|
||
else
|
||
{
|
||
base.NamingStrategy = null;
|
||
}
|
||
|
||
|
||
IList<JsonProperty> 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
|
||
|
||
|
||
|
||
}
|
||
}
|
||
}
|