简体   繁体   English

您如何使用Json.net修改仅一个字段的Json序列化?

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

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. 例如,我正在尝试将具有10个字段的对象转换为Json,但是我需要修改序列化其中1个字段的过程。 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? 有没有办法让Json.net自动序列化除一个属性以外的所有属性? Or possibly generate a JObject automatically and modify that? 或者可能会自动生成一个JObject并对其进行修改?

You can try by decorating the property you need to modify manually with JsonConverterAttribute and pass the appropriate JsonConverter type. 您可以尝试使用JsonConverterAttribute装饰需要手动修改的属性,并传递适当的JsonConverter类型。

For example, using OP's original example: 例如,使用OP的原始示例:

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 : 然后,您可以照常使用JsonConvert序列化对象:

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

var jsonString = JsonConvert.SerializeObject(test);

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: 如果希望将值4序列化为int,则可以执行以下操作:

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

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

You might use System.Reflection , however it's slow but you don't have to modify the class 您可以使用System.Reflection ,但是速度很慢,但是不必修改类

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM