Files
zszq-trs/Framework/YLErp.Core/Helpers/JsonHelper.cs
T
2024-05-09 14:06:26 +08:00

350 lines
11 KiB
C#

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using YLErp.Commons;
using YLErp.Helpers;
namespace System
{
/// <summary>
/// JSON序列化/反序列化帮助类(使用json.net)
/// </summary>
public static class JsonHelper
{
/// <summary>
/// 将JSON字符串反序列化为对象,如果json字符串为null或空字符串,返回default(T)
/// </summary>
public static T ToObject<T>(string json)
{
return string.IsNullOrWhiteSpace(json) ? default : JsonConvert.DeserializeObject<T>(json, settings[(int)SerializeSetting.all]);
}
/// <summary>
/// 将JSON字符串反序列化为对象,如果json字符串为null或空字符串,返回default(T)
/// </summary>
public static T Parse<T>(string json)
{
return string.IsNullOrWhiteSpace(json) ? default : JsonConvert.DeserializeObject<T>(json, settings[(int)SerializeSetting.all]);
}
/// <summary>
/// 将JSON字符串反序列化为对象,如果json字符串为null或空字符串,返回default(T)
/// </summary>
public static T Deserialize<T>(string json)
{
return string.IsNullOrWhiteSpace(json) ? default : JsonConvert.DeserializeObject<T>(json, settings[(int)SerializeSetting.all]);
}
public static T DeserializeIgnoreNull<T>(string json)
{
var settings = new JsonSerializerSettings
{
Error = (obj, args2) =>
{
args2.ErrorContext.Handled = true;
}
};
return string.IsNullOrWhiteSpace(json) ? default : JsonConvert.DeserializeObject<T>(json, settings);
}
//---------------------------------------------------------------------------------
/// <summary>
/// 将对象序列化为JSON格式,如果对象为null,返回string.empty
/// </summary>
public static string ToJson(this object obj, bool ignoreNullValue = true, bool camelCase = false)
{
if (obj == null)
{
return string.Empty;
}
if (obj is Collections.Specialized.NameValueCollection nv)
{
obj = nv.AllKeys.ToDictionary(k => k, k => nv[k]);
}
else if (obj is IEnumerable<object> arr && arr.Count() == 0)
{
return "[]";
}
var setting = SerializeSetting.none;
if (ignoreNullValue)
{
setting = SerializeSetting.ignoreNull;
}
if (camelCase)
{
setting |= SerializeSetting.camelCase;
}
return JsonConvert.SerializeObject(obj, settings[(int)setting]);
}
/// <summary>
/// 将对象序列化为JSON格式,如果对象为null,返回string.empty
/// </summary>
public static string Stringify(object obj, bool ignoreNullValue = true, bool camelCase = false)
{
return ToJson(obj, ignoreNullValue, camelCase);
}
/// <summary>
/// 将对象序列化为JSON格式,如果对象为null,返回string.empty
/// </summary>
public static string Serialize(object obj, bool ignoreNullValue = true, bool camelCase = false)
{
return ToJson(obj, ignoreNullValue, camelCase);
}
//---------------------------------------------------------------------------------
/// <summary>
///
/// </summary>
public static JsonSerializerSettings GetDefaultSettings()
{
var setting = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
setting.Converters.Insert(0, DateOnlyJsonConverter.Default);
return setting;
}
//---------------------------------------------------------------------------------
static readonly JsonSerializerSettings[] settings;
static JsonHelper()
{
settings = new JsonSerializerSettings[1 + (int)SerializeSetting.all];
var defaultSettings = new JsonSerializerSettingsEx();
settings[(int)SerializeSetting.none] = defaultSettings;
settings[(int)SerializeSetting.ignoreNull] = defaultSettings.Clone().Set(n => n.NullValueHandling = NullValueHandling.Ignore);
settings[(int)SerializeSetting.camelCase] = defaultSettings.Clone().Set(n => n.ContractResolver = new CamelCasePropertyNamesContractResolver());
settings[(int)(SerializeSetting.ignoreNull | SerializeSetting.camelCase)] = defaultSettings.Clone().Set(n =>
{
n.NullValueHandling = NullValueHandling.Ignore;
n.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
foreach (var s in settings)
{
if (s.Converters != null)
{
s.Converters.Insert(0, DateOnlyJsonConverter.Default);
}
else
{
s.Converters = new List<JsonConverter> { DateOnlyJsonConverter.Default };
}
}
}
class JsonSerializerSettingsEx : JsonSerializerSettings
{
public JsonSerializerSettingsEx()
{
DateFormatString = "yyyy-MM-dd HH:mm:ss";
ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
}
public JsonSerializerSettingsEx Set(Action<JsonSerializerSettingsEx> setter)
{
setter(this);
return this;
}
public JsonSerializerSettingsEx Clone()
{
return (JsonSerializerSettingsEx)MemberwiseClone();
}
}
/// <summary>
/// json序列化配置枚举
/// </summary>
enum SerializeSetting
{
none = 0,
ignoreNull = 1,
camelCase = 2,
all = ignoreNull | camelCase
}
}
/// <summary>
/// 支持解析单个或数组格式到集合
/// 在IEnumerable[T]泛型定义的字段上加JsonConverterAttribute
/// [JsonConverter(typeof(SingleOrArrayConverter<string>))]
/// </summary>
public class SingleOrArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(IEnumerable<T>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
if (token.Type == JTokenType.Array)
{
return token.ToObject<T[]>();
}
return new T[] { token.ToObject<T>() };
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 支持解析单个或数组格式到集合(空字符串将被过滤掉)
/// </summary>
public class StringArrayConverter : SingleOrArrayConverter<string>
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
if (token.Type == JTokenType.Array)
{
return token.ToObject<string[]>().Where(n => !string.IsNullOrWhiteSpace(n)).ToArray();
}
var str = token.ToObject<string>();
return string.IsNullOrWhiteSpace(str) ? Array.Empty<string>() : new[] { str };
}
}
/// <summary>
///
/// </summary>
class DateOnlyJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value?.ToString());
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var nullable = ReflectionHelper.IsNullableType(objectType);
if (reader.TokenType == JsonToken.Null)
{
if (nullable)
{
return null;
}
return new YcDateOnly(DateTime.MinValue);
}
if (reader.TokenType == JsonToken.Date)
{
return new YcDateOnly((DateTime)reader.Value);
}
if (reader.TokenType != JsonToken.String)
{
throw new JsonSerializationException($"Unexpected token parsing date. Expected String, got {reader.TokenType},value:{reader.Value}");
}
var dateText = reader.Value?.ToString();
if (string.IsNullOrWhiteSpace(dateText))
{
if (nullable)
{
return null;
}
return DateTime.MinValue;
}
var dt = DateTime.Parse(dateText, Globalization.CultureInfo.InvariantCulture);
return new YcDateOnly(dt);
}
public override bool CanRead => true;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(YcDateOnly) || objectType == typeof(YcDateOnly?);
}
public static readonly DateOnlyJsonConverter Default;
static DateOnlyJsonConverter()
{
Default = new DateOnlyJsonConverter();
}
}
/// <summary>
/// 用于格式化double数据
/// </summary>
public class DoubleJsonWriteConverter : JsonConverter
{
readonly OtcFormatOption _format;
public DoubleJsonWriteConverter(int minDecimals, int maxDecimals)
{
if (minDecimals < 0)
{
minDecimals = 0;
}
if (maxDecimals < minDecimals)
{
maxDecimals = minDecimals;
}
_format = new OtcFormatOption
{
minDecimals = minDecimals,
maxDecimals = maxDecimals,
grouping = false,
percent = false,
rounded = true
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
}
else if (value is double d)
{
writer.WriteValue(_format.FormatValue(d));
}
else
{
var d2 = (double?)value;
writer.WriteValue(_format.FormatValue(d2.Value));
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanRead => false;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(double) || objectType == typeof(double?);
}
}
}