Reputation: 405
I am using JsonConvert.DeserializeObject(json.ToString()); to deserialise a JSON and populate my fields in a related model. This works well until there is data missing in the JSON. Basically instead of having "key : value" I will just have "key : null".
My understanding about the JsonConverter was that it would create an object, in which I should be able to populate fields with a default value either through the constructor (not being called in my case for unknown reasons), or through the tags as mentioned here: Default value for missing properties with JSON.net or here: Why when I deserialize with JSON.NET ignores my default value?
I have tried both and neither results in the related fields being initialised. Of course if there is no data in the JSON, nothing can be deserialised to the related model. However I would expect that I still could initialise some values with defaults, which would then just be ignored (not overwritten) by JsonConverter (just like what happens now). This however, does not seem to be possible?
Source code of previous attempts
Model class
namespace Project.MyJob
{
public class JsonModel
{
public JsonModel()
{
Type_X type_x = new Type_X();
// This is not doing anything. I would have expected that the
// class' constructor would be called but, no.
}
public string objectNumber { get; set; }
public string objectFamily { get; set; }
public string objectOrder { get; set; }
public string location { get; set; }
public string place { get; set; }
public string inventionTime { get; set; }
public string lastUpdate { get; set; }
public string condition { get; set; }
public Type_X Type_X { get; set; }
public List<Actions> actions { get; set; }
}
public class Actions
{
public string count { get; set; }
public string datetime { get; set; }
public string place { get; set; }
public string status { get; set; }
}
public class Type_X
{
public Type_X
{
// This should be executed when a new Type_X object is created? Also
// not.
partA = "null";
}
[DefaultValue("null")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public string partA { get; set; }
// Trying public string partA { get; set; } = "null"; also does
// nothing.
[DefaultValue("null")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public string PartB { get; set; }
[DefaultValue("null")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public string partC { get; set; }
[DefaultValue("null")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public string partD { get; set; }
[DefaultValue("null")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public string partE { get; set; }
}
}
Creation of JSON object with default values (defaults not working)
JObject = JsonConvert.DeserializeObject<JsonModel>(json.ToString(), new
JsonSerializerSettings {DefaultValueHandling =
DefaultValueHandling.Populate});
Example of downstream usage of the created objects
JObject.actions[i].count + "more text"
Above works when not relying on defaults.
Upvotes: 3
Views: 7591
Reputation: 129777
You are using the wrong setting.
If you want null
values in the JSON to be ignored during deserialization, you need to set NullValueHandling = NullValueHandling.Ignore
in the settings. The default is Include
, which means that if the JSON has an explicit null
in it for a particular property, that property will be set to null on your object, overwriting any default you may have set.
DefaultValueHandling.Populate
means if the key is missing altogether in the JSON (which is different from being set to null), then it will use the value provided by the [DefaultValue]
attribute. Note that if the JSON has an explicit null
in it, this setting will not use the default value from the attribute, even if NullValueHandling
is set to Ignore
. So if you want a default value in that situation, the best way to do that is by setting it in the constructor.
So, in short, to get the behavior you want:
NullValueHandling.Ignore
setting.DefaultValueHandling
setting or the [DefaultValue]
attribute.Demo fiddle: https://dotnetfiddle.net/kyUjFz
Upvotes: 11