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)
{
//// 会影响 string? 传递null 变为""
var isNullable1 = _memberInfo.CustomAttributes.Any(a => a.AttributeType.Name == "NullableAttribute");
if (_memberInfo.PropertyType == typeof(string) && isNullable1 == false)
{
//如果不处理 前段传递null string不会接收,说前段没传递会验证报错
_memberInfo.SetValue(target, value == null ? string.Empty : value);
}
else
{
_memberInfo.SetValue(target, value);
}
//if ()
//{
// //去掉前后空格
// _memberInfo.SetValue(target, value == null ? string.Empty : value.ToString() == string.Empty ? value : value/*.ToString().Trim()*/);
//}
//else
//{
// _memberInfo.SetValue(target, value);
//}
}
}
}