我正在使用Json.NET将类序列化为JSON。
我有这样的课程:
class Test1
{
[JsonProperty("id")]
public string ID { get; set; }
[JsonProperty("label")]
public string Label { get; set; }
[JsonProperty("url")]
public string URL { get; set; }
[JsonProperty("item")]
public List<Test2> Test2List { get; set; }
}
我希望仅在JsonIgnore()
为Test2List
时向Test2List
属性添加null
属性。如果它不为null,那么我想将它包含在我的json中。
答案 0 :(得分:759)
使用JsonProperty
属性的替代解决方案:
[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
// or
[JsonProperty("property_name", NullValueHandling=NullValueHandling.Ignore)]
// or for all properties in a class
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
如this online doc中所示。
答案 1 :(得分:579)
根据James Newton King的说法:如果您自己创建序列化程序而不是使用JavaScriptConvert,则可以设置NullValueHandling
property来忽略。
以下是一个示例:
JsonSerializer _jsonWriter = new JsonSerializer {
NullValueHandling = NullValueHandling.Ignore
};
或者,正如@amit
所建议的那样JsonConvert.SerializeObject(myObject,
Newtonsoft.Json.Formatting.None,
new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore
});
答案 2 :(得分:51)
与@ sirthomas的答案类似,JSON.NET也尊重DataMemberAttribute
上的the EmitDefaultValue
property:
[DataMember(Name="property_name", EmitDefaultValue=false)]
如果您已在模型类型中使用[DataContract]
和[DataMember]
并且不想添加特定于JSON.NET的属性,则可能需要这样做。
答案 3 :(得分:24)
你可以写:[JsonProperty("property_name",DefaultValueHandling = DefaultValueHandling.Ignore)]
它还负责不使用默认值(不仅为null)序列化属性。例如,它可用于枚举。
答案 4 :(得分:20)
您可以这样做来忽略您要序列化的对象中的所有空值,然后任何空属性都不会出现在JSON中
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
var myJson = JsonConvert.SerializeObject(myObject, settings);
答案 5 :(得分:10)
可以在他们网站上的这个链接中看到(http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size。 aspx)我支持使用[Default()]指定默认值
取自链接
public class Invoice
{
public string Company { get; set; }
public decimal Amount { get; set; }
// false is default value of bool
public bool Paid { get; set; }
// null is default value of nullable
public DateTime? PaidDate { get; set; }
// customize default values
[DefaultValue(30)]
public int FollowUpDays { get; set; }
[DefaultValue("")]
public string FollowUpEmailAddress { get; set; }
}
Invoice invoice = new Invoice
{
Company = "Acme Ltd.",
Amount = 50.0m,
Paid = false,
FollowUpDays = 30,
FollowUpEmailAddress = string.Empty,
PaidDate = null
};
string included = JsonConvert.SerializeObject(invoice,
Formatting.Indented,
new JsonSerializerSettings { });
// {
// "Company": "Acme Ltd.",
// "Amount": 50.0,
// "Paid": false,
// "PaidDate": null,
// "FollowUpDays": 30,
// "FollowUpEmailAddress": ""
// }
string ignored = JsonConvert.SerializeObject(invoice,
Formatting.Indented,
new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
// {
// "Company": "Acme Ltd.",
// "Amount": 50.0
// }
答案 6 :(得分:4)
适应@Mychief的/ @ amit的答案,但适用于使用VB的人
(?s)(?=protocol udp).*(inactivity-timeout (?!1800))
请参阅: "Object Initializers: Named and Anonymous Types (Visual Basic)"
答案 7 :(得分:0)
稍微阐述一下GlennG非常有用的答案(将语法从C#转换为VB.Net并不总是“显而易见”)你还可以修饰单个类属性来管理如何处理空值。如果这样做,请不要使用GlennG建议的全局JsonSerializerSettings,否则它将覆盖单个装饰。如果您希望在JSON中显示空项目,那么这会派上用场,因此消费者不必进行任何特殊处理。例如,如果消费者需要知道一系列可选项目通常是可用的,但目前是空的...... 财产声明中的装饰如下:
<JsonPropertyAttribute("MyProperty", DefaultValueHandling:=NullValueHandling.Include)> Public Property MyProperty As New List(of String)
对于那些您不希望在JSON更改中显示的属性:= NullValueHandling.Include 到:= NullValueHandling.Ignore 。 顺便说一句 - 我发现你可以为XML和JSON序列化装饰一个属性就好了(只需将它们放在彼此旁边)。这使我可以随意调用dotnet中的XML序列化程序或NewtonSoft序列化程序 - 两者并排工作,我的客户可以选择使用XML或JSON。由于我的顾客需要两者,所以这就像门把手上的鼻涕一样光滑!
答案 8 :(得分:0)
这是一个类似的选项,但提供了另一种选择:
public class DefaultJsonSerializer : JsonSerializerSettings
{
public DefaultJsonSerializer()
{
NullValueHandling = NullValueHandling.Ignore;
}
}
然后,我这样使用它:
JsonConvert.SerializeObject(postObj, new DefaultJsonSerializer());
这里的区别在于:
JsonSerializerSettings
每个使用过的地方来减少重复的代码。答案 9 :(得分:0)
在.Net Core中,这现在变得容易得多。在您的startup.cs中,只需添加json选项,即可在此处配置设置。
public void ConfigureServices(IServiceCollection services)
....
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});
答案 10 :(得分:0)
使用Json.NET
list = soup.find_all('tr')
for item in list:
print(item.attrib) #continuously prints none
结果将是:
list = soup.find_all('tr')
for item in list:
print(item.find('tr')['bicolor'])
答案 11 :(得分:0)
借助System.Text.Json
和.NET Core 3.0,它为我工作了:
var jsonSerializerOptions = new JsonSerializerOptions()
{
IgnoreNullValues = true
};
var myJson = JsonSerializer.Serialize(myObject, jsonSerializerOptions );
答案 12 :(得分:0)
这不能完全回答原始问题,但是根据使用情况可能会证明是有用的。 (而且由于搜索后我在这里清醒,对其他人可能会有用。)
根据我最近的经验,我正在使用PATCH api。如果指定了属性但没有给出值(由于是js,则为null / undefined),则该属性和值将从正在修补的对象中删除。因此,我一直在寻找一种方法来有选择地构建一个对象,该对象可以以一种可行的方式进行序列化。
我记得曾经看过ExpandoObject,但是直到今天才有真正的用例。这使您可以动态地构建对象,因此除非您希望在其中存在null属性,否则您将没有null属性。
Here是一个工作提琴,下面的代码。
结果:
Standard class serialization
noName: {"Name":null,"Company":"Acme"}
noCompany: {"Name":"Fred Foo","Company":null}
defaultEmpty: {"Name":null,"Company":null}
ExpandoObject serialization
noName: {"Company":"Acme"}
noCompany: {"name":"Fred Foo"}
defaultEmpty: {}
代码:
using Newtonsoft.Json;
using System;
using System.Dynamic;
public class Program
{
public static void Main()
{
SampleObject noName = new SampleObject() { Company = "Acme" };
SampleObject noCompany = new SampleObject() { Name = "Fred Foo" };
SampleObject defaultEmpty = new SampleObject();
Console.WriteLine("Standard class serialization");
Console.WriteLine($" noName: { JsonConvert.SerializeObject(noName) }");
Console.WriteLine($" noCompany: { JsonConvert.SerializeObject(noCompany) }");
Console.WriteLine($" defaultEmpty: { JsonConvert.SerializeObject(defaultEmpty) }");
Console.WriteLine("ExpandoObject serialization");
Console.WriteLine($" noName: { JsonConvert.SerializeObject(noName.CreateDynamicForPatch()) }");
Console.WriteLine($" noCompany: { JsonConvert.SerializeObject(noCompany.CreateDynamicForPatch()) }");
Console.WriteLine($" defaultEmpty: { JsonConvert.SerializeObject(defaultEmpty.CreateDynamicForPatch()) }");
}
}
public class SampleObject {
public string Name { get; set; }
public string Company { get; set; }
public object CreateDynamicForPatch()
{
dynamic x = new ExpandoObject();
if (!string.IsNullOrWhiteSpace(Name))
{
x.name = Name;
}
if (!string.IsNullOrEmpty(Company))
{
x.Company = Company;
}
return x;
}
}
答案 13 :(得分:-1)
new Handler().postDelayed(theRunnable, 1000);