.NET Core 2.2, публикация всех библиотек DLL в папку ref из пакета AspNetCore.App

В комментариях похоже, что вы решили прибегнуть к использованию Regex, чтобы избавиться от пустых объектов. Одна из проблем с этой идеей заключается в том, что она, вероятно, не будет обрабатывать ситуацию, когда у вас есть то, что я назову «рекурсивные пустые объекты». Другими словами, что-то вроде этого:

{
    "foo":
    {
        "bar": {},
        "baz": {}
    }
}

Если вам удастся удалить самые глубокие уровни пустых объектов bar и baz с помощью Regex (при этом также понимая, что вам нужно удалить запятую между ними, чтобы сохраните JSON действительным), вы все равно оставите пустой объект: foo.

{
    "foo":
    {
    }
}

Я думаю, что лучшим решением является загрузка ваших данных в иерархию JToken, а затем использование рекурсивного чтобы удалить все пустые дети, прежде чем записывать их в JSON. Что-то вроде этого должно работать для ваших нужд:

using System;
using Newtonsoft.Json.Linq;

public static class JsonHelper
{
    public static string SerializeToMinimalJson(object obj)
    {
        return JToken.FromObject(obj).RemoveEmptyChildren().ToString();
    }

    public static JToken RemoveEmptyChildren(this JToken token)
    {
        if (token.Type == JTokenType.Object)
        {
            JObject copy = new JObject();
            foreach (JProperty prop in token.Children())
            {
                JToken child = prop.Value;
                if (child.HasValues)
                {
                    child = child.RemoveEmptyChildren();
                }
                if (!child.IsEmptyOrDefault())
                {
                    copy.Add(prop.Name, child);
                }
            }
            return copy;
        }
        else if (token.Type == JTokenType.Array)
        {
            JArray copy = new JArray();
            foreach (JToken item in token.Children())
            {
                JToken child = item;
                if (child.HasValues)
                {
                    child = child.RemoveEmptyChildren();
                }
                if (!child.IsEmptyOrDefault())
                {
                    copy.Add(child);
                }
            }
            return copy;
        }
        return token;
    }

    public static bool IsEmptyOrDefault(this JToken token)
    {
        return (token.Type == JTokenType.Array && !token.HasValues) ||
               (token.Type == JTokenType.Object && !token.HasValues) ||
               (token.Type == JTokenType.String && token.ToString() == String.Empty) ||
               (token.Type == JTokenType.Boolean && token.Value() == false) ||
               (token.Type == JTokenType.Integer && token.Value() == 0) ||
               (token.Type == JTokenType.Float && token.Value() == 0.0) || 
               (token.Type == JTokenType.Null);
    }

}

Затем вы можете сериализовать свой объект (ы) следующим образом:

var json = JsonHelper.SerializeToMinimalJson(obj);

Fiddle: https: // dotnetfiddle.net/awRPMR

EDIT

Если вы хотите почитать атрибут [DefaultValue] с помощью этого метода, вы можете сделать это, изменив метод SerializeToMinimalJson() на создайте экземпляр JsonSerializer, установив на него свойство DefaultValueHandling, а затем передав его в JToken.FromObject(), как показано ниже. (Это нужно сделать так, потому что у JTokens нет ссылок на исходные объекты, из которых они были созданы с помощью FromObject(), поэтому после этого невозможно получить значения атрибутов [DefaultValue].)

public static string SerializeToMinimalJson(object obj)
{
    var serializer = new JsonSerializer();
    serializer.NullValueHandling = NullValueHandling.Ignore;
    serializer.DefaultValueHandling = DefaultValueHandling.Ignore;
    return JToken.FromObject(obj, serializer).RemoveEmptyChildren().ToString();
}

Если вы это сделаете, вы также можете изменить метод IsEmptyOrDefault(), чтобы он не удалял значения, которые являются стандартными по умолчанию. Вы можете уменьшить его до:

public static bool IsEmptyOrDefault(this JToken token)
{
    return (token.Type == JTokenType.Array && !token.HasValues) ||
           (token.Type == JTokenType.Object && !token.HasValues);
}

Fiddle: https://dotnetfiddle.net/0yVRI5

0
задан ekad 19 January 2019 в 03:11
поделиться