私は 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; }
}
Test2List
がnull
の場合に限り、JsonIgnore()
属性をTest2List
プロパティに追加します。それがnullでないならば、私は私のJSONにそれを含めたいです。
James Newton Kingによると、JavaScriptConvertを使用するのではなく自分でシリアライザを作成する場合は、 NullValueHandling
プロパティ を使用して無視できます。
これがサンプルです:
JsonSerializer _jsonWriter = new JsonSerializer {
NullValueHandling = NullValueHandling.Ignore
};
あるいは、@ amitが示唆しているように
JsonConvert.SerializeObject(myObject,
Newtonsoft.Json.Formatting.None,
new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore
});
JsonProperty
属性を使用した別の解決策:
[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
// or
[JsonProperty("property_name", NullValueHandling=NullValueHandling.Ignore)]
// or for all properties in a class
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
@ sirthomasの答えと同様に、JSON.NETも EmitDefaultValue
プロパティ on DataMemberAttribute
を尊重します。
[DataMember(Name="property_name", EmitDefaultValue=false)]
モデルタイプに[DataContract]
と[DataMember]
を既に使用していて、JSON.NET固有の属性を追加したくない場合は、これが望ましいかもしれません。
あなたは書くことができます:[JsonProperty("property_name",DefaultValueHandling = DefaultValueHandling.Ignore)]
プロパティをデフォルト値で直列化しないようにします(nullだけではありません)。たとえば列挙型には便利です。
これを行うと、直列化しているオブジェクト内のすべてのnullを無視することができ、nullプロパティはJSONに表示されません。
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
var myJson = JsonConvert.SerializeObject(myObject, settings);
彼らのサイト(http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size.aspx)のこのリンクで見られることができるように、Iデフォルト値を指定するための[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
// }
@ Mrchief's/@ amit's answerへの適応、しかしVBを使っている人へ
Dim JSONOut As String = JsonConvert.SerializeObject(
myContainerObject,
New JsonSerializerSettings With {
.NullValueHandling = NullValueHandling.Ignore
}
)
GlennGの非常に有用な答え(C#からVB.Netへの構文の変換は常に "明白"とは限らない)を少し説明すると、個々のクラスプロパティを装飾してnull値の処理方法を管理することもできます。これを行う場合、GlennGの提案によるグローバルなJsonSerializerSettingsを使用しないでください。それ以外の場合は、個々の装飾が上書きされます。これは、コンシューマが特別な処理をする必要がないように、null項目を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を使用することができます。私は両方を必要とする顧客を持っているので、これはドアノブの上の目印のように滑らかです!
これは似たオプションですが、別の選択肢があります。
public class DefaultJsonSerializer : JsonSerializerSettings
{
public DefaultJsonSerializer()
{
NullValueHandling = NullValueHandling.Ignore;
}
}
それから、私はこのようにそれを使います:
JsonConvert.SerializeObject(postObj, new DefaultJsonSerializer());
違いは、次のとおりです。
JsonSerializerSettings
をインスタンス化して構成することで、繰り返しコードを削減します。.Net Coreでは、これがはるかに簡単になりました。 startup.csにjsonオプションを追加するだけで、そこで設定を構成できます。
public void ConfigureServices(IServiceCollection services)
....
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});
Json.NETを使用
public class Movie
{
public string Name { get; set; }
public string Description { get; set; }
public string Classification { get; set; }
public string Studio { get; set; }
public DateTime? ReleaseDate { get; set; }
public List<string> ReleaseCountries { get; set; }
}
Movie movie = new Movie();
movie.Name = "Bad Boys III";
movie.Description = "It's no Bad Boys";
string ignored = JsonConvert.SerializeObject(movie,
Formatting.Indented,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
結果は次のようになります。
{
"Name": "Bad Boys III",
"Description": "It's no Bad Boys"
}