Royi Namir
Royi Namir

Reputation: 148524

Change JSON.net content via property name?

I have this structure :

  List<dynamic> lst = new List<dynamic>();
  lst.Add(new{objId = 1,myOtherColumn = 5});
  lst.Add(new{objId = 2,myOtherColumn = 6});
  lst.Add(new{lala = "asd" ,lala2 = 7});

I'm serializing it via :

 string st= JsonConvert.SerializeObject(lst);

Question:

How can I cause the serializer to change only values of the "objId" property , to something else ?

I know I should use class Myconverter : JsonConverter , but I didn't find any example which keeps the default behavior and in addition - allow me to add condition logic of serialization.

Upvotes: 0

Views: 275

Answers (1)

James Thorpe
James Thorpe

Reputation: 32202

Here's a converter that will handle it, at least for simple objects as per your example. It looks for objects containing objId properties and then serialises all properties it finds on them. You may need to expand it to deal with other member types/more complex properties as required:

class MyConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        foreach (var prop in value.GetType().GetProperties()) {
            writer.WritePropertyName(prop.Name);
            if (prop.Name == "objId") {
                //modify objId values for example
                writer.WriteValue(Convert.ToInt32(prop.GetValue(value, null)) + 10); 
            } else {
                writer.WriteValue(prop.GetValue(value, null));
            }                
        }
        writer.WriteEndObject();
    }

    public override bool CanConvert(Type objectType)
    {
        //only attempt to handle types that have an objId property
        return (objectType.GetProperties().Count(p => p.Name == "objId") == 1);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Alternatively, you can use a converter that specifies it will only convert int types, then query where in the JSON path you are before doing any conversions. This has the benefit of not needing to deal with all the other members of the anonymous type.

class MyConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (writer.Path.EndsWith(".objId")) {
            writer.WriteValue(Convert.ToInt32(value) + 10);
        }
        else {
            writer.WriteValue(value);
        }
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof (int);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Upvotes: 2

Related Questions