我有这个示例转换器的guid属性:
public class CustomGuidConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof (Guid?) || objectType == typeof (Guid);
}
public override void WriteJson(JsonWriter writer, object oldValue, JsonSerializer serializer)
{
if (value != null)
{
var newValue = convert(oldValue); // do some conversion
writer.WriteValue(newValue);
}
}
}
像这样使用
public class Outer {
public int Id { get; set; }
[JsonConverter(typeof(InterfaceLabelConverter))]
public Guid? ProductFamilyId { get; set; }
}
如何访问WriteJson
方法中当前属性的名称?我想用另一个属性名将旧值写入writer,像这样:
{ Id: 1234, ProductFamilyId: 'newValue', ProductFamilyIdOld: 'oldValue' }
我建议简单地将转换后的GUID作为包含类的私有get-only属性。如果你用[JsonProperty]
标记它,它将被序列化:
public class Outer
{
public int Id { get; set; }
public Guid? ProductFamilyId { get; set; }
[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
Guid? OldProductFamilyId
{
get
{
return Convert(ProductFamilyId);
}
}
private Guid? Convert(Guid? guid)
{
if (guid != null)
{
var bytes = guid.Value.ToByteArray();
bytes[0] = unchecked((byte)~bytes[0]); // For example
guid = new Guid(bytes);
}
return guid;
}
}
也就是说,你可以从JsonWriter.Path
属性中选择当前属性名:
public class InterfaceLabelConverter : JsonConverter
{
private Guid? Convert(Guid? guid)
{
if (guid != null)
{
var bytes = guid.Value.ToByteArray();
bytes[0] = unchecked((byte)~bytes[0]); // For example
guid = new Guid(bytes);
}
return guid;
}
public override bool CanConvert(Type objectType)
{
throw new InvalidOperationException(); // This converter should only be applied directly to a property.
}
public override bool CanRead { get { return false; } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var path = writer.Path;
var propertyName = path.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Last(); // Throw an exception if not found.
if (propertyName.StartsWith("[") && propertyName.EndsWith("]"))
throw new InvalidOperationException(); // Trying to use this converter for an array element.
var guid = (Guid?)value;
writer.WriteValue(guid);
if (guid != null)
{
// Note -- actually the converter isn't called for null values, see
// https://stackoverflow.com/questions/8833961/serializing-null-in-json-net
var nextGuid = Convert(guid);
var nextName = "Old" + propertyName;
writer.WritePropertyName(nextName);
writer.WriteValue(nextGuid);
}
}
}
并像这样使用:
public class Outer
{
public int Id { get; set; }
[JsonConverter(typeof(InterfaceLabelConverter))]
public Guid? ProductFamilyId { get; set; }
}