Поместите ваш плавающий div(s)
в div
и в CSS дайте ему overflow:hidden;
, он будет работать нормально.
В комментариях похоже, что вы решили прибегнуть к использованию 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<JProperty>())
{
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<bool>() == false) ||
(token.Type == JTokenType.Integer && token.Value<int>() == 0) ||
(token.Type == JTokenType.Float && token.Value<double>() == 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
Вы можете дать JsonSerializerSettings
методу, используя NullValueHandling.Ignore
:
var output = JsonConvert.SerializeObject(obj, new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore
});
Если эти настройки не дают то, что вам нужно, проверьте: документацию. Здесь вы можете найти все свойства и описание.
Изменить: использование дочернего элемента (Sample) в качестве структуры, которое работает с DefaultValueHandling.Ignore. Но @ Zoltán Tamási будет использовать регулярное выражение из-за сложности класса.
Sample
, как и по умолчанию (поскольку по умолчанию для ссылки является null
). Надеюсь, вы понимаете, что я имею в виду
– Zoltán Tamási
27 April 2016 в 09:25
Я реализовал немного другое решение, которое использует общий метод, отражение и некоторую стандартную функциональность Newtonsoft.Json ShouldSerialize. Не элегантный, но концептуально простой для моей конкретной потребности. Ниже приведен фрагмент кода LinqPad.
void Main()
{
Person person = new Person();
person.MyAddress = new Address();
var ret = person.ShouldSerializeMyAddress();
var json = JsonConvert.SerializeObject(person, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
json.Dump();
}
public static class JsonExtensions
{
public static bool ShouldSerialize(this object self)
{
if (self == null)
return false;
var methods = self.GetType().GetMethods().Where(p => p.Name.StartsWith("ShouldSerialize"));
return methods.Any(p => p.Invoke(self, null) is bool value && value);
}
}
public class Person
{
public Address MyAddress { get; set; }
public bool ShouldSerializeMyAddress()
{
return MyAddress.ShouldSerialize();
}
}
public class Address
{
public string Street { get; set; }
public bool ShouldSerializeStreet()
{
return false; // or whatever your property serialization criteria should be
}
public string City { get; set; }
public bool ShouldSerializeCity()
{
return false;
}
public string State { get; set; }
public bool ShouldSerializeState()
{
return false;
}
public string Zip { get; set; }
public bool ShouldSerializeZip()
{
return false;
}
}
DefaultValueAttribute
при проверке, является ли значение токена «стандартным» ?? – Zoltán Tamási 28 April 2016 в 07:01DefaultValueAttribute
. Кроме того, вы правы, я полагаю, что Regex будет работать, если вы будете применять его повторно в цикле до тех пор, пока не будет сделано никаких замен. Ну, вы, конечно, можете свободно использовать любой метод, который лучше всего подходит для вашей ситуации. Теперь у вас есть еще один инструмент в панели инструментов. – Brian Rogers 28 April 2016 в 15:10