直接 上 代码:
public class Entity { [JsonConverter(typeof(EntityIdJsonConverter))]//这个有没有效果都一样 public EntityId Id { get; set; } } [JsonConverter(typeof(EntityIdJsonConverter))] public struct EntityId { public Guid Id { get; set; }
public override string ToString()
{
return this.Id.ToString();
}
public static implicit operator Guid(EntityId objId) => objId.Id; public static implicit operator EntityId(Guid objId) => new EntityId { Id = objId }; public static implicit operator string(EntityId objId) => objId.Id.ToString(); public static implicit operator EntityId(string objId) => new EntityId { Id = Guid.Parse(objId) }; } internal sealed class EntityIdJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) { return true; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { string value = reader.ReadAsString(); Expression exp = Expression.Constant(value); exp = Expression.Convert(exp, objectType); var l = Expression.Lambda(exp); return l.Compile().DynamicInvoke(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteRawValue(value.ToString()); } }
下面是调试代码:
var entity = new Entity{Id = Guid.NewGuid()}; var json = JsonConvert.SerializeObject(entity); //触发了转换器的函数 WriteJson //结果 : { "Id":"guid字符串"},正确,满足我需要 var entity2 = JsonConvert.DeserializeObject<Entity>(json); //报告错误,未触发 转换器函数 ReadJson
因为你的json字符串就已经错了,所以到不了ReadJson那儿去,你可以考虑修改WriteJson方法:
writer.WriteRawValue($"\"{value.ToString()}\"");
来构造一个标准的json字符串,这个时候就能够进入到ReadJson里面去了。
牛!还真没注意序列化后的json数据不是一个字符串。
@519740105: 实际测试,发现进入到ReadJson还是会报错。这里面需要针对不同的类型单独处理。
@幻天芒: 我这个Converter限制在这个EntityId范畴,输入数据限制为GUID格式的字符串。问题倒不大。
再去考虑多种可能的兼容,成本太高了。
序列化得到的并不是json
这个是需求。