1

Is it possible to have only values found in a Json string be assigned by the Newtonsoft Json.NET deserializer even if they are default and null values being assigned?

Using the example below, I'm attempting to find values that are added to the _values dictionary when the properties are set. In Json 1, all values are set and saved to the database. In Json 2, the identifier is set and Value is updated to null. After deserialization, I will find the values in the database and want to update only fields with a value in the dictionary. This issue is, assigning null doesn't actually set the value because it is the default value.

As of now, I seem to be able to ignore defaults but then Value: null is ignored. Or I can Include defaults and Name is assigned null even though it isn't in the Json.

I know I could add...

[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]

but on serialization, I'd like to ignore defaults.

Deserializer Code

var jsonSerializer = new JsonSerializer();
var widget = jsonSerializer.Deserialize<Widget>(jsonString);

Serializer Code

var serializer = new JsonSerializer
{
     DefaultValueHandling = DefaultValueHandling.Ignore
};
var jsonString = serializer.Serialize(widget);

Example class

public class Widget
{
    [JsonProperty]
    public int Id { get { return Get<int>("Id"); } set { Set("Id", value); } }

    [JsonProperty]
    public string Name { get { return Get<string>("Name"); } set { Set("Name", value); } }

    [JsonProperty]
    public string Value { get { return Get<string>("Value"); } set { Set("Value", value); } }

    private Dictionary<sting, object> _values = new Dictionary<sting, object>();
    private object Get<T>(string name)
    {
        if (_values.TryGetValue(name, out value))
            return (T)value;
        else
            return default(T);
    }
    private void Set(string name, object value)
    {
        _values[name] = value;
    }
}

Example Json 1

{
    "Id": 6,
    "Name": "Widget 1",
    "Value": "Blue"
}

Example Json 2

{
    "Id": 6
    "Value": null
}
2
  • 1
    How are you deserializing the JSON in the first place and to what? I really don't follow what you are trying to do. Commented Sep 30, 2016 at 18:33
  • You might want to take a look at Modify existing object with new partial JSON data using Json.NET. This sounds like the same problem you are trying to solve. It uses serializer.PopulateObject to do a partial update. So the strategy would be: load the existing object, patch it using PopulateObject, then save the object back to your data store. Commented Sep 30, 2016 at 19:30

1 Answer 1

1

You may make use of ShouldSerialize methods, e.g.

bool ShouldSerializeName() {
    return _values.ContainsKey("Name");
}

bool ShouldSerializeValue() {
    return _values.ContainsKey("Value");
}

Not pretty but it should work. Another option is a custom serializer.

Sign up to request clarification or add additional context in comments.

1 Comment

I see where you are going with this. Would need to add [JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)] for deserialization and these methods for serialization. Thing is, I have 500+ properties in my project. May need to do this with IContractResolver.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.