Newtonsoft JSON泛型包装类通过隐式转换实现序列化问题排查
问题原因
- 你为
SofT<T>的TValue字段添加了[JsonProperty]注解,Newtonsoft.Json 会优先将SofT<T>识别为包含内部序列化成员的复杂对象,直接序列化该字段输出嵌套结构,不会触发你定义的隐式转换逻辑。 - 序列化阶段 Newtonsoft.Json 不会主动调用用户定义的
隐式转string运算符,仅当类型没有可序列化的标记成员时,才会调用ToString()方法生成序列化结果。 - 反序列化阶段能正常工作是因为输入JSON字段为字符串类型,Newtonsoft.Json 反序列化时会自动查找匹配的
从string到SofT<T>的隐式转换,因此可以正常生成对象。
修复方案(无需自定义JsonConverter)
仅需要对SofT<T>结构体做两处小修改即可:
- 移除
TValue上的[JsonProperty]注解,避免Json.NET将其识别为序列化成员 - 重写
ToString()方法,将隐式转string的逻辑同步到该方法中,供Json.NET序列化时调用
修改后的完整代码如下:
using Newtonsoft.Json; using System; namespace test { public struct SofT<T> { // 移除JsonProperty注解 public T TValue { get; set; } public static implicit operator SofT<T>(string jtoken) { return new SofT<T>() { TValue = (T)Convert.ChangeType(jtoken, typeof(T)) }; } public static implicit operator string(SofT<T> soft) { return soft.ToString(); } // 新增重写ToString方法 public override string ToString() { return TValue?.ToString() ?? string.Empty; } } [JsonObject(MemberSerialization.OptIn)] public class Something { [JsonProperty] public SofT<int> TestStructInt { get; set; } [JsonProperty] public SofT<decimal> TestStructDecimal { get; set; } } public class Program { public void Run() { var json = "{ \"TestStructInt\" : \"12\", \"TestStructDecimal\" : \"3.45\"}"; var modelDeserialised = JsonConvert.DeserializeObject<Something>(json); var modelReserialised = JsonConvert.SerializeObject(modelDeserialised); Console.WriteLine(modelReserialised); // 输出结果:{"TestStructInt":"12","TestStructDecimal":"3.45"} } static void Main(string[] args) { new Program().Run(); } } }
内容的提问来源于stack exchange,提问作者Michael D O'Shea
相关产品推荐
相关产品推荐

