C#中使用Newtonsoft.Json格式化输出

需求

  1. 如果属性内容为- 则替换为null
  2. 如果属性内容为""则替换为null
  3. 如果一个节点下面的属性内容全部为null则将修改为[]

示例如下:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;

public class TestClass
{
    public string PropertyA { get; set; }
    public string PropertyB { get; set; }
    public NestedClass Nested { get; set; }
    public List<NestedClass> Nesteds { get; set; }
}

public class NestedClass
{
    public string NestedPropertyA { get; set; }
    public string NestedPropertyB { get; set; }
}

public class CustomConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var obj = JObject.FromObject(value);
        ProcessJToken(obj);
        obj.WriteTo(writer);
    }

    private void ProcessJToken(JToken token)
    {
        if (token is JObject obj)
        {
            foreach (var property in obj.Properties().ToList())
            {
                ProcessJToken(property.Value);
                
                if (property.Value.Type == JTokenType.String && (
                    property.Value.ToString() == "-" || 
                    property.Value.ToString() == ""))
                {
                    property.Value.Replace(JValue.CreateNull());
                }
            }

            if (obj.Properties().All(p => p.Value.Type == JTokenType.Null))
            {
                obj.RemoveAll();
            }
        }
        else if (token is JArray arr)
        {
            foreach (var item in arr.ToList())
            {
                ProcessJToken(item);
            }

            if (arr.Children<JObject>().All(item => item.Properties().All(p => p.Value.Type == JTokenType.Null)))
            {
                arr.Replace(new JArray());
            }
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader);
        ProcessJToken(token);
        return token.ToObject(objectType);
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }
}

class Program
{
    static void Main()
    {
        var json = @"{
            ""PropertyA"": ""-"",
            ""PropertyB"": """",
            ""Nested"": {
                ""NestedPropertyA"": ""-"",
                ""NestedPropertyB"": ""-""
            },
            ""Nesteds"": [{
                ""NestedPropertyA"": ""-"",
                ""NestedPropertyB"": ""-""
            }]
        }";

		var settings = new JsonSerializerSettings
		{
		    Converters = { new CustomConverter() },
		    Formatting = Newtonsoft.Json.Formatting.Indented
		};

        var obj = JsonConvert.DeserializeObject<JObject>(json, settings);

        var resultJson = JsonConvert.SerializeObject(obj, settings);

        Console.WriteLine(resultJson);
    }
}

结果如下所示:

1. 格式化输出前

{
  "PropertyA": "-",
  "PropertyB": "",
  "Nested": {
    "NestedPropertyA": "-",
    "NestedPropertyB": "-"
  },
  "Nesteds": [
    {
      "NestedPropertyA": "-",
      "NestedPropertyB": "-"
    }
  ]
}

2. 格式化输出后

{
  "PropertyA": null,
  "PropertyB": null,
  "Nested": {},
  "Nesteds": []
}

C#使用typeof进行处理

1. 代码如下:

public static void RecursiveRemoveFormerName<T>(T t)
{
    if (t == null) return;

    if (t is List<FormerName> toRemove)
    {
        RemoveEmptyEntries(toRemove);
    }

    Type typeofT = t.GetType();

    if (IsSimpleType(typeofT))
    {
        return;
    }
    else if (t is IEnumerable enumerable)
    {
        foreach (var item in enumerable)
        {
            RecursiveRemoveFormerName(item);
        }
    }
    else
    {
        foreach (PropertyInfo prop in typeofT.GetProperties())
        {
            var obj = prop.GetValue(t);
            RecursiveRemoveFormerName(prop.GetValue(t));
        }
    }

    static bool IsSimpleType(Type type)
    {
        if (type.IsEnum)
            return true;

        TypeCode typeCode = Type.GetTypeCode(type);
        switch (typeCode)
        {
            case TypeCode.Boolean:
            case TypeCode.Byte:
            case TypeCode.Char:
            case TypeCode.DateTime:
            case TypeCode.Decimal:
            case TypeCode.Double:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
            case TypeCode.SByte:
            case TypeCode.Single:
            case TypeCode.String:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
                return true;
            default:
                return false;
        }
    }
}
static void RemoveEmptyEntries(List<FormerName> toRemove)
{
    for (int i = 0; i < toRemove.Count; ++i)
    {
        FormerName name = toRemove[i];
        if (string.IsNullOrEmpty(name.EffectiveDate) && string.IsNullOrEmpty(name.Name))
        {
            toRemove.RemoveAt(i);
            --i;
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值