C#中将JsonPatchDocument序列化为字符串时value属性丢失如何解决
问题原因
JsonPatchDocument<T> 自带的Newtonsoft.Json专属序列化转换器有强类型校验逻辑,当value为弱类型JObject/JToken结构、未匹配到泛型T的实体属性结构时,默认转换器会直接忽略该字段,导致序列化后丢失value属性。
解决方法
方案1:临时移除专属转换器(最快生效)
序列化时指定配置,移除JsonPatchDocument专属转换器,使用通用对象序列化逻辑即可保留完整value结构:
var serializeSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Include, // 过滤掉JsonPatchDocument专属转换器 Converters = JsonConvert.DefaultSettings?.Invoke().Converters .Where(c => c.GetType() != typeof(JsonPatchDocumentConverter)) .ToList() ?? new List<JsonConverter>() }; string result = JsonConvert.SerializeObject(patchDocument, serializeSettings);
方案2:反序列化时指定强类型
如果JsonPatchDocument对应的操作实体结构固定,反序列化时直接指定泛型类型,后续序列化就会自动识别value结构:
// 假设你要操作的实体类为Expense var patchDocument = JsonConvert.DeserializeObject<JsonPatchDocument<Expense>>(inputJson); // 直接序列化即可正常输出value string result = JsonConvert.SerializeObject(patchDocument);
方案3:自定义转换器适配弱类型场景
如果需要兼容任意类型的value值,可以自定义转换器强制序列化所有操作字段:
public class FullJsonPatchConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(JsonPatchDocument) || (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(JsonPatchDocument<>)); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var patchDoc = value as IJsonPatchDocument; var operations = patchDoc.GetOperations(); // 强制序列化op、path、from、value四个核心字段 serializer.Serialize(writer, operations.Select(op => new { op.op, op.path, op.from, op.value })); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // 反序列化复用默认逻辑 return new JsonPatchDocumentConverter().ReadJson(reader, objectType, existingValue, serializer); } }
使用时添加到序列化配置即可:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new FullJsonPatchConverter()); string result = JsonConvert.SerializeObject(patchDocument, settings);
内容的提问来源于stack exchange,提问作者Serhat
相关产品推荐
相关产品推荐

