c# – 如何在生成的JSON中省略/忽略/跳过空对象文字?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 如何在生成的JSON中省略/忽略/跳过空对象文字?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3512字,纯文字阅读大概需要6分钟。
内容图文
![c# – 如何在生成的JSON中省略/忽略/跳过空对象文字?](/upload/InfoBanner/zyjiaocheng/810/d7cff9d546684f6bb8d40f914b80e49d.jpg)
我正在使用Json.NET将复杂的C#对象图转换为JSON.由于忽略了对象中具有默认值的属性,我通常在输出中得到空对象文字,我想省略它.
例如:
public class Sample {
public int Value { get; set; }
public string Name { get; set; }
}
public class ParentSample {
// this property should never be null, hence the initializer
public Sample Sample { get; } = new Sample();
}
..
var obj = new ParentSample();
// settings for indentation and excluding default values omitted for clarity
var output = JsonConvert.SerializeObject(obj, ... );
// output will be
// {
// Sample: {}
// }
//
// I'd like it to be
// {}
我知道一些特定类型的解决方案,比如将一个ShouldSerializeSample布尔方法添加到ParentSample类型,并检查所有属性是否都是默认属性.但是,我想以自定义合约解析器的形式提供一般解决方案.
解决方法:
在评论中,您似乎决定使用正则表达式去除空对象.这个想法的一个问题是它可能无法处理你将拥有我称之为“递归空对象”的情况.换句话说,这样的事情:
{
"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);
小提琴:https://dotnetfiddle.net/awRPMR
编辑
如果要使用此方法来遵循[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);
}
小提琴:https://dotnetfiddle.net/0yVRI5
内容总结
以上是互联网集市为您收集整理的c# – 如何在生成的JSON中省略/忽略/跳过空对象文字?全部内容,希望文章能够帮你解决c# – 如何在生成的JSON中省略/忽略/跳过空对象文字?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。