您的位置:首页 > 健康 > 美食 > Newtonsoft.Json对象转JSON字符串全集

Newtonsoft.Json对象转JSON字符串全集

2024/12/23 9:26:32 来源:https://blog.csdn.net/dystocia/article/details/142173082  浏览:    关键词:Newtonsoft.Json对象转JSON字符串全集

需求:对象转为JSON字符串时可以同时满足以下5点。

1、同一个类中不同字段支持自定义日期格式,如:“2024-10-01”,“2024-10-01 12:12:12”;

2、string、datetime 为null时转为空字符串;int、decimal为null时转为0;对象为null时转为{};集合为null时转为[];

3、long类型可以转为字符串;

4、枚举可以用“value、name、display” 做为json字符串的值;

5、小数点可以保留完整。

现实如下:

第1/3步:自定义ActionResult

public class CustomsJsonResult : ActionResult
{public object Value { get; private set; }  public string ContentType { get;  set; }public CustomsJsonResult(object _value){Value = _value;}/// <summary>/// 时间默认格式/// </summary>public string formatter = "yyyy-MM-dd HH:mm:ss";/// <summary>///枚举转换/// </summary>public bool StringEnumConverter = false;public override void ExecuteResult(ActionContext context){if (context == null){context.HttpContext.Response.WriteAsync("{}");}var response = context.HttpContext.Response;response.ContentType =  string.IsNullOrEmpty(ContentType) ? "application/json": ContentType;var jsonSerizlizerSetting = new JsonSerializerSettings() {//设置取消循环引用MissingMemberHandling = MissingMemberHandling.Ignore,ReferenceLoopHandling = ReferenceLoopHandling.Ignore,//设置日期的格式为:yyyy-MM-ddDateFormatString = formatter,//自定义的解析协议ContractResolver = new NullToEmptyStringResolver()};if (StringEnumConverter){//转换枚举CamelCaseNamingStrategy _CamelCaseNamingStrategy = new CamelCaseNamingStrategy { ProcessExtensionDataNames = true };//转换时使用枚举jsonProperty    [JsonConverter(typeof(EnumPropertyNameConverter)]jsonSerizlizerSetting.Converters.Add(new Models.EnumPropertyNameConverter { });//数字转为字符串  [JsonConverter(typeof(StringEnumConverter)]jsonSerizlizerSetting.Converters.Add(new StringEnumConverter { NamingStrategy = _CamelCaseNamingStrategy });}//日期转换格式jsonSerizlizerSetting.Converters.Add(new DateTimeFormat());//默认时间格式处理jsonSerizlizerSetting.Converters.Add(new DateFormat());//默认时间格式处理//时间转换格式//long转为字符串jsonSerizlizerSetting.Converters.Add(new Models.NumberToStrConverter { });//jsonSerizlizerSetting.Converters.Add(new DecimalPrecisionConverter(6));//序列化CardData出现内存溢出var json = JsonConvert.SerializeObject(Value, Formatting.None, jsonSerizlizerSetting);context.HttpContext.Response.WriteAsync(json);}}

第2/3步:自定义解析协议,这里主要实现null转换。

/// <summary>/// JSON自定义解析协议/// </summary>public class NullToEmptyStringResolver : Newtonsoft.Json.Serialization.DefaultContractResolver{protected override IValueProvider CreateMemberValueProvider(System.Reflection.MemberInfo member){if (member.MemberType == MemberTypes.Property){var pi = (PropertyInfo)member;if (pi.PropertyType == typeof(string)|| pi.PropertyType.BaseType == typeof(object)|| pi.PropertyType == typeof(DateTime)|| pi.PropertyType == typeof(DateTime?)|| pi.PropertyType == typeof(decimal?)){return new NullableJsonValueProvider(pi);}}return base.CreateMemberValueProvider(member);}}//    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)//    {//        return type.GetProperties()//                .Select(p => {//                    var jp = base.CreateProperty(p, memberSerialization);//                    jp.ValueProvider = new NullToEmptyStringValueProvider(p);//                    return jp;//                }).ToList();//    }//}/// <summary>///空值序列化提供程序/// </summary>public class NullableJsonValueProvider : IValueProvider{private static readonly string _defaultValue = string.Empty;private readonly PropertyInfo _propertyInfo;public NullableJsonValueProvider(PropertyInfo propertyInfo){_propertyInfo = propertyInfo;}public void SetValue(object target, object value){_propertyInfo.SetValue(target, value);}public object GetValue(object target){var result = _propertyInfo.GetValue(target);if (result != null){return result;}if (_propertyInfo.PropertyType == typeof(string)|| _propertyInfo.PropertyType == typeof(DateTime)|| _propertyInfo.PropertyType == typeof(DateTime?)){return _defaultValue;}//decimal型转为0else if (_propertyInfo.PropertyType == typeof(Nullable<decimal>))return 0M;//int型转为0else if (_propertyInfo.PropertyType == typeof(Nullable<int>))return 0;//集合转为[]else if (_propertyInfo.PropertyType.IsGenericType){return new List<Newtonsoft.Json.Linq.JObject>(0);}//对象转为{}else if (_propertyInfo.PropertyType.BaseType == typeof(object)){if (_propertyInfo.PropertyType != typeof(string) && result == null){return  new Newtonsoft.Json.Linq.JObject();}}return result;}}

第3/3步:定义转换器

//yyyy-MM-dd日期的格式 
public class DateFormat : JsonConverter{public string format = "yyyy-MM-dd";public DateFormat(){}public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer){if (value is DateTime dateTime){writer.WriteValue(dateTime.ToString(format));}else{writer.WriteNull();}}public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer){if (reader.TokenType == JsonToken.Null)return null;if (reader.TokenType == JsonToken.String){string text = reader.Value.ToString();if (DateTime.TryParse(text, out DateTime dateTime)){return dateTime;}}throw new Exception($"Cannot convert {reader.TokenType} to {objectType}.");}public override bool CanConvert(Type objectType){return objectType == typeof(DateTime);}}//yyyy-MM-dd HH:mm:ss日期的格式public class DateTimeFormat : JsonConverter{public string format = "yyyy-MM-dd HH:mm:ss";public DateTimeFormat(){}public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer){if (value is DateTime dateTime){writer.WriteValue(dateTime.ToString(format));}else{writer.WriteNull();}}public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer){if (reader.TokenType == JsonToken.Null)return null;if (reader.TokenType == JsonToken.String){string text = reader.Value.ToString();if (DateTime.TryParse(text, out DateTime dateTime)){return dateTime;}}throw new Exception($"Cannot convert {reader.TokenType} to {objectType}.");}public override bool CanConvert(Type objectType){return objectType == typeof(DateTime);}}/// <summary>/// 数字类型转为字符串/// </summary>public sealed class NumberToStrConverter : JsonConverter{/// <summary>/// 转换成字符串的类型/// </summary>private readonly NumberConverterShip _ship;/// <summary>/// 大数据json序列化重写实例化/// </summary>public NumberToStrConverter(){_ship = (NumberConverterShip)0xFF;}/// <summary>/// 大数据json序列化重写实例化/// </summary>/// <param name="ship">转换成字符串的类型</param>public NumberToStrConverter(NumberConverterShip ship){_ship = ship;}/// <inheritdoc />/// <summary>/// 确定此实例是否可以转换指定的对象类型。/// </summary>/// <param name="objectType">对象的类型。</param>/// <returns>如果此实例可以转换指定的对象类型,则为:<c>true</c>,否则为:<c>false</c></returns>public override bool CanConvert(Type objectType){var typecode = Type.GetTypeCode(objectType.Name.Equals("Nullable`1") ? objectType.GetGenericArguments().First() : objectType);switch (typecode){case TypeCode.Int64:return (_ship & NumberConverterShip.Int64) == NumberConverterShip.Int64;//  case TypeCode.Decimal://  return (_ship & NumberConverterShip.Decimal) == NumberConverterShip.Decimal;//  case TypeCode.Double://   return (_ship & NumberConverterShip.Double) == NumberConverterShip.Double;// case TypeCode.UInt64://   return (_ship & NumberConverterShip.UInt64) == NumberConverterShip.UInt64;// case TypeCode.Single://   return (_ship & NumberConverterShip.Single) == NumberConverterShip.Single;default: return false;}}/// <inheritdoc />/// <summary>/// 读取对象的JSON表示。/// </summary>/// <param name="reader">从 <see cref="T:Newtonsoft.Json.JsonReader" /> 中读取。</param>/// <param name="objectType">对象的类型。</param>/// <param name="existingValue">正在读取的对象的现有值。</param>/// <param name="serializer">调用的序列化器实例。</param>/// <returns>对象值。</returns>public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer){if (reader.TokenType == JsonToken.Null){return "";}return AsType(reader.Value.ToString(), objectType);}/// <summary>/// 字符串格式数据转其他类型数据/// </summary>/// <param name="input">输入的字符串</param>/// <param name="destinationType">目标格式</param>/// <returns>转换结果</returns>public static object AsType(string input, Type destinationType){try{var converter = TypeDescriptor.GetConverter(destinationType);if (converter.CanConvertFrom(typeof(string))){return converter.ConvertFrom(null, null, input);}converter = TypeDescriptor.GetConverter(typeof(string));if (converter.CanConvertTo(destinationType)){return converter.ConvertTo(null, null, input, destinationType);}}catch{return null;}return null;}/// <inheritdoc />/// <summary>/// 写入对象的JSON表示形式。/// </summary>/// <param name="writer">要写入的 <see cref="T:Newtonsoft.Json.JsonWriter" /> 。</param>/// <param name="value">要写入对象值</param>/// <param name="serializer">调用的序列化器实例。</param>public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer){if (value == null){writer.WriteNull();}else{var objectType = value.GetType();var typeCode = Type.GetTypeCode(objectType.Name.Equals("Nullable`1") ? objectType.GetGenericArguments().First() : objectType);switch (typeCode){case TypeCode.Int64:writer.WriteValue(((long)value).ToString());break;//case TypeCode.Decimal://  writer.WriteValue(((decimal)value).ToString("f6"));//  break;//  case TypeCode.Double://  writer.WriteValue(((double)value).ToString("f4"));//   break;// case TypeCode.Single://   writer.WriteValue(((float)value).ToString("f2"));//  break;// default://  writer.WriteValue(value.ToString());// break;}}}

.Net MVC项目使用演示:  

        protected ActionResult Json(object data,string ContentType = "application/json", string formatter= "yyyy-MM-dd HH:mm:ss",bool StringEnumConverter=false) {var res= new CustomsJsonResult(data){ContentType = ContentType,StringEnumConverter = StringEnumConverter,formatter = formatter};return res;}

其中的data就是我们要转为json字符串的数据 。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com