I have a class that is annotated with DataContract and DataMember attributes. Some members are marked as DataMember(IsRequired = true)
. When I serialize instances over the wire from Json.NET, and the required object members have null value, then their serialized values are missing in the output (which is apparently equivalent to being null in JSON). I'm okay with that.
I've created a sort of "echo" service which returns data sent to it as a response. So this service receives the JSON with missing members (or null members depending on how you look at it), and then sends it right back to my Json.NET client. The JSON on the wire looks the same in both directions as viewed through Fiddler (a proxy sniffer). So far so good.
When the original Json.NET sender receives the JSON response to deserialize it, the serializer throws an exception about not finding required members in the JSON payload:
Required property 'IAmRequired' not found in JSON. Path ''.
That is unfortunate, as the serializer is thus not able to deserialize data that it had previously serialized without a problem.
Short of changing the DataContract class to make the member not required (which I do not want to do for a number of reasons), is there a way to make Json.NET deserialize missing members to default values such as null?
Here is my deserialization code:
HasRequired h = null;
JObject json = response as JObject; // hand waving here
try
{
JsonSerializer ser = new JsonSerializer();
ser.MissingMemberHandling = MissingMemberHandling.Ignore; // doesn't seem to help
ser.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; // doesn't seem to help
ser.NullValueHandling = NullValueHandling.Include; // doesn't seem to help
h = json.ToObject<HasRequired>(ser);
}
catch (Exception ex)
{
// bummer, missing required members still
}
A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.
JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).
Serialization and deserialization in . NET application, JSON data format conversion to . NET objects and vice versa is very common. Serialization is the process of converting . NET objects such as strings into a JSON format and deserialization is the process of converting JSON data into . NET objects.
MissingMemberHandling Property. Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. The default value is Ignore. Namespace: Newtonsoft.Json.
If you have properties marked with [DataMember(Required = true)]
and you want to override the required behavior, there are a couple of things you can do:
You can mark those same properties with [JsonProperty(Required = Required.Default)]
. This works because [JsonProperty]
takes precedence over [DataMember]
in Json.Net.
[DataContract]
public class HasRequired
{
[DataMember(Required = true)]
[JsonProperty(Required = Required.Default)]
public string IAmRequired { get; set; }
}
Or, you can create a custom ContractResolver that programmatically sets Required = Required.Default
on every property.
class CustomResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
prop.Required = Required.Default;
return prop;
}
}
To use the resolver, simply set the ContractResolver
property on the serializer to a new instance of the custom resolver:
JsonSerializer ser = new JsonSerializer();
ser = new CustomResolver();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With