当前位置: 首页 > 编程语言 > C#

如何在生成的JSON中省略-忽略-跳过空对象文字?Share

时间:2023-04-10 15:37:00 C#

如何在生成的JSON中省略/忽略/跳过空对象文字?我正在使用Json.NET将复杂的C#对象图转换为JSON。由于具有默认值的对象中的属性会被忽略,因此我通常会在输出中得到空的对象字面量,我想将其忽略。例如:publicclassSample{publicintValue{get;放;}公共字符串名称{得到;放;}}publicclassParentSample{//这个属性不应该为null,因此初始化器publicSampleSample{get;}=新样本();}..varobj=newParentSample();//设置缩进并排除默认值,为清楚起见省略varoutput=JsonConvert.SerializeObject(obj,...);//输出将是//{//示例:{}//}////我希望它是//{}我知道一些特定于类型的解决方案,例如向ParentSample添加ShouldSerializeSample布尔方法类型并检查是否所有属性都是默认属性。但是,我想以自定义合同解析器的形式提供通用解决方案。在评论中,您似乎决定使用正则表达式来摆脱空对象。这个想法的一个问题是它可能无法处理我称之为“递归空对象”的情况。换句话说,像这样:{"foo":{"bar":{},"baz":{}}}如果你设法用正则表达式删除最深的空对象bar和baz(同时也意识到你需要删除它们之间的逗号保持JSON有效),你仍然会留下一个空对象:foo。{"foo":{}}我认为更好的解决方案是将数据加载到JToken层次结构中,并在将数据写入JSON之前使用递归方法删除所有空子项。这种情况应该适合您的需求:usingSystem;使用Newtonsoft.Json.Linq;publicstaticclassJsonHelper{publicstaticstringSerializeToMinimalJson(objectobj){returnJToken.FromObject(obj).RemoveEmptyChildren().ToString();}publicstaticJTokenRemoveEmptyChildren(thisJTokentoken){if(token.Type==JTokenType.Object){JObjectcopy=newJObject();foreach(JPropertypropintoken.Children()){JTokenchild=prop.Value;如果(child.HasValues){child=child.RemoveEmptyChildren();}if(!child.IsEmptyOrDefault()){copy.Add(prop.Name,child);}}返回副本;}elseif(token.Type==JTokenType.Array){JArraycopy=newJArray();foreach(token.Children()中的JToken项目){JTokenchild=item;如果(child.HasValues){child=child.RemoveEmptyChildren();}if(!child.IsEmptyOrDefault()){copy.Add(child);}}返回副本;}返回令牌;}publicstaticboolIsEmptyOrDefault(thisJTokentoken){return(token.Type==JTokenType.Array&&!token.Has值)||(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);然后你可以像这样序列化你的对象:varjson=JsonHelper.SerializeToMinimalJson(obj);小提琴:https://dotnetfiddle。net/awRPMR编辑如果你想用这个方法跟随[DefaultValue]属性,你可以通过修改SerializeToMinimalJson()方法创建JsonSerializer的实例,在JsonSerializer中设置DefaultValueHandling属性,然后将它传递给JToken.FromObject()如下所示(必须以Thiswayit'sdone结尾,因为JTokens没有对原始对象的引用,它们是使用FromObject()创建的,因此之后无法获取[DefaultValue]属性的值。)publicstaticstringSerializeToMinimalJson(objectobj){varserializer=newJsonSerializer();serializer.NullValueHandling=NullValueHandling.Ignore;serializer.DefaultValueHandling=DefaultValueHandling.Ignore;);如果这样做,您可能还想更改IsEmptyOrDefault()方法,以便它不会删除作为“默认默认值”的值。您可以将其简化为:publicstaticboolIsEmptyOrDefault(thisJTokentoken){return(token.Type==JTokenType.Array&&!token.HasValues)||(token.Type==JTokenType.Object&&!token.HasValues);小提琴:https://dotnetfiddle.net/0yVRI5您可以使用JsonSerializerSettings为方法提供NullValueHandling.Ignore:varoutput=JsonConvert.SerializeObject(obj,newJsonSerializerSettings(){NullValueHandling=NullValueHandling.Ignore});如果此设置不能满足您的需求,请查看:Documentation。您可以在那里找到所有属性和描述。编辑:使用sub(Sample)作为结构,它与DefaultValueHandling.Ignore一起工作。但由于类的复杂性,@ZoltánTamási将使用正则表达式。我实现了一个稍微不同的解决方案,它使用通用方法、反射和一些默认的Newtonsoft.JsonShouldSerialize函数。不优雅,但在概念上很简单,可以满足我的特殊需求。下面是LinqPad代码片段。以上是C#学习教程:Howtoomit/ignore/skipemptyobjectliteralsinthegeneratedJSON?分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注。person.MyAddress=newAddress();varret=person.ShouldSerializeMyAddress();varjson=JsonConvert.SerializeObject(person,Newtonsoft.Json.Formatting.Indented,newJsonSerializerSettings{NullValueHandling=NullValueHandling.Ignore});json.转储();}publicstaticclassJsonExtensions{publicstaticShouldSerialize(thisobjectself){if(self==null)returnfalse;变种方法=自我。获取类型()。获取方法()。Where(p=>p.Name.StartsWith("ShouldSerialize"));返回方法。Any(p=>p.Invoke(self,null)isboolvalue&&value);}}publicclassPerson{publicAddressMyAddress{get;放;}publicboolShouldSerializeMyAddress(){returnMyAddress.ShouldSerialize();}}publicclassAddress{publicstringStreet{get;放;}publicboolShouldSerializeStreet(){返回假;//或者任何你认为合适的ty序列化标准应该是}publicstringCity{get;放;}publicboolShouldSerializeCity(){返回false;}公共字符串状态{得到;放;}publicboolShouldSerializeState(){返回假;}publicstringZip{得到;放;}publicboolShouldSerializeZip(){返回假;}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: