比如说我试图将一个包含10个字段的对象转换为Json,但是我需要修改序列化其中一个字段的过程。目前,我必须手动写出每个属性,如下所示:
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();
}
这不是很好的代码,而且写作真的很烦人。有没有办法让Json.net自动序列化除一个属性以外的所有属性?或者可能自动生成一个JObject并修改它?
答案 0 :(得分:4)
您可以尝试使用JsonConverterAttribute
手动修改需要修改的属性,并传递相应的JsonConverter
类型。
例如,使用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; }
}
然后,您可以照常使用JsonConvert
序列化对象:
var test = new TestJson {Field1 = "1", Field2 = "2", Field3 = "3", Field4 = "4"};
var jsonString = JsonConvert.SerializeObject(test);
答案 1 :(得分:1)
如果您有权访问该类(并且您始终需要以相同的方式对其进行序列化),则可以根据需要修改该类。假设this.is是班级:
public class MyClass
{
public string Value4 {get; set;}
}
如果您希望将值4序列化为int,则可以执行此操作:
public class MyClass
{
[JsonIgnore()]
public string Value4 {get; set;}
public int Value4AsInt
{
return Convert.ToInt32(Value4);
}
}
答案 2 :(得分:1)
你可以使用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();
}