irc-netcore-api/IRaCIS.Core.API/_ServiceExtensions/NewtonsoftJson/NullToEmptyStringResolver.cs

142 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)
{
#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?
//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
}
}
}