'How to add an extra property into a serialized JSON string using json.net?

I am using Json.net in my MVC 4 program.

I have an object item of class Item.

I did: string j = JsonConvert.SerializeObject(item);

Now I want to add an extra property, like "feeClass" : "A" into j.

How can I use Json.net to achieve this?



Solution 1:[1]

You have a few options.

The easiest way, as @Manvik suggested, is simply to add another property to your class and set its value prior to serializing.

If you don't want to do that, the next easiest way is to load your object into a JObject, append the new property value, then write out the JSON from there. Here is a simple example:

class Item
{
    public int ID { get; set; }
    public string Name { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Item item = new Item { ID = 1234, Name = "FooBar" };
        JObject jo = JObject.FromObject(item);
        jo.Add("feeClass", "A");
        string json = jo.ToString();
        Console.WriteLine(json);
    }
}

Here is the output of the above:

{
  "ID": 1234,
  "Name": "FooBar",
  "feeClass": "A"
}

Another possibility is to create a custom JsonConverter for your Item class and use that during serialization. A JsonConverter allows you to have complete control over what gets written during the serialization process for a particular class. You can add properties, suppress properties, or even write out a different structure if you want. For this particular situation, I think it is probably overkill, but it is another option.

Solution 2:[2]

Following is the cleanest way I could implement this

dynamic obj = JsonConvert.DeserializeObject(jsonstring);
obj.NewProperty = "value";
var payload = JsonConvert.SerializeObject(obj);

Solution 3:[3]

You could use ExpandoObject. Deserialize to that, add your property, and serialize back.

Pseudocode:

Expando obj = JsonConvert.Deserializeobject<Expando>(jsonstring);
obj.AddeProp = "somevalue";
string addedPropString = JsonConvert.Serializeobject(obj);

Solution 4:[4]

I think the most efficient way to serialize a property that doesn't exist in the type is to use a custom contract resolver. This avoids littering your class with the property you don't want, and also avoids the performance hit of the extra serialization round trip that most of the other options on this page incur.

public class SpecialItemContractResolver : DefaultContractResolver {

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) {
        var list = base.CreateProperties(type, memberSerialization);
        if (type.Equals(typeof(Item))) {
            var feeClassProperty = CreateFeeClassProperty();
            list.Add(feeClassProperty);
        }
        return list;
    }

    private JsonProperty CreateFeeClassProperty() {
        return new JsonProperty {
            PropertyName = "feeClass",
            PropertyType = typeof(string),
            DeclaringType = typeof(Item),
            ValueProvider = new FeeClassValueProvider(),
            AttributeProvider = null,
            Readable = true,
            Writable = false,
            ShouldSerialize = _ => true
        };
    }

    private class FeeClassValueProvider : IValueProvider {
        public object GetValue(object target) => "A";
        public void SetValue(object target, object value) { }
    }

}

To use this functionality:

// This could be put in a static readonly place so it's reused
var serializerSettings = new JsonSerializerSettings {
    ContractResolver = new SpecialItemContractResolver()
};

// And then to serialize:
var item = new Item();
var json = JsonConvert.Serialize(item, serializerSettings);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 tubakaya
Solution 3 roland
Solution 4