How do you modify the Json serialization of just one field using Json.net?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-20 02:53:10

问题


Say for example I'm trying to convert an object with 10 fields to Json, however I need to modify the process of serializing 1 of these fields. At the moment, I'd have to use manually write out each property like this:

 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteStartObject();

        writer.WritePropertyName("Field1");
        serializer.Serialize(writer, value.Field1);

        writer.WritePropertyName("Field2");
        serializer.Serialize(writer, value.Field2);

        writer.WritePropertyName("Field3");
        serializer.Serialize(writer, value.Field3);

        writer.WritePropertyName("Field4");
        serializer.Serialize(writer, Convert.ToInt32(value.Field4)); //Modifying one field here

        //Six more times

        writer.WriteEndObject();
    }

This isn't good code, and it's really irritating to have to write. Is there any way of getting Json.net to serialize all but one property automatically? Or possibly generate a JObject automatically and modify that?


回答1:


You can try by decorating the property you need to modify manually with JsonConverterAttribute and pass the appropriate JsonConverter type.

For example, using OP's original example:

public class IntegerConverter : JsonConverter
{
  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  {
    serializer.Serialize(writer, Convert.ToInt32(value));
  }

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

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

class TestJson
{
  public string Field1 { get; set; }
  public string Field2 { get; set; }
  public string Field3 { get; set; }

  [JsonConverter(typeof(IntegerConverter))]
  public string Field4 { get; set; }        
}

You can then serialize the object as usual using JsonConvert:

var test = new TestJson {Field1 = "1", Field2 = "2", Field3 = "3", Field4 = "4"};

var jsonString = JsonConvert.SerializeObject(test);



回答2:


If you have access to the class (and you always need it to be serialized the same way) you could modify the class to your needs. Suppose this.is the class:

public class MyClass
{
    public string Value4 {get; set;}
}

If you want value 4 to be serialized as an int you could do this:

public class MyClass
{
    [JsonIgnore()]
    public string Value4 {get; set;}

    public int Value4AsInt
    {
        return Convert.ToInt32(Value4);
    }
}



回答3:


You might use System.Reflection, however it's slow but you don't have to modify the class

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    writer.WriteStartObject();

    Type vType = value.GetType();
    MemberInfo[] properties = vType.GetProperties(BindingFlags.Public
                                        | BindingFlags.Instance);

    foreach (PropertyInfo property in properties)
    {
        object serValue = null;
        if (property.Name == "Field4")
        {
            serValue = Convert.ToInt32(property.GetValue(value, null));
        }
        else
        {
            serValue = property.GetValue(value, null);
        }
        writer.WritePropertyName(property.Name);
        serializer.Serialize(writer, serValue);
    }

    writer.WriteEndObject();
}


来源:https://stackoverflow.com/questions/21182758/how-do-you-modify-the-json-serialization-of-just-one-field-using-json-net

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!