如何避免已含有效JSON字符串的字段被重复序列化?
如何避免已含有效JSON的字段被重复序列化?
问题背景
我在ASP.NET中返回包含JSON字符串的对象列表时遇到了重复序列化的问题:
- 定义了从数据库读取数据的实体类:
public class ObjectToSerialize { public string Identifier { get; set; } public string JsonPayload { get; set; } public ObjectToSerialize() { Identifier = string.Empty; JsonPayload = string.Empty; } }
- 从数据库读取数据并填充列表:
List<ObjectToSerialize> listOfObjects = new List<ObjectToSerialize>(); // 省略数据库查询逻辑 while (sqlDataReader.Read()) { // 省略字段赋值逻辑 listOfObjects.Add(new ObjectToSerialize()); }
- 通过
OkObjectResult返回列表,默认会自动序列化:
return new OkObjectResult(listOfObjects);
其中JsonPayload字段本身已经是有效的JSON字符串,但返回时会被当成普通字符串再次序列化,导致输出带转义符的字符串。我不想先反序列化再重新序列化,也不想用[JsonIgnore]或[NonSerialized]把字段删掉,希望直接让JsonPayload以原生JSON对象的形式输出。
示例
设置值:
var obj = new ObjectToSerialize { Identifier = "123", JsonPayload = @" { ""ThisIsAKey"" : ""ThisIsAValue"" }" };
期望输出:
{ "Identifier" : "123", "JsonPayload" : { "ThisIsAKey" : "ThisIsAValue" } }
实际输出:
{ "Identifier" : "123", "JsonPayload" : "{ \"ThisIsAKey\" : \"ThisIsAValue\" }" }
解决方案:自定义JsonConverter
针对不同的JSON序列化库,实现对应的自定义转换器,让序列化时直接把JsonPayload的字符串内容作为原生JSON写入,跳过转义步骤。
情况1:使用Newtonsoft.Json(ASP.NET MVC/早期Core版本)
实现JsonConverter类:
using Newtonsoft.Json; using System.IO; public class RawJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) { // 仅处理string类型字段 return objectType == typeof(string); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // 反序列化时直接返回字符串 return reader.Value?.ToString(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is string jsonString && !string.IsNullOrEmpty(jsonString)) { // 写入原始JSON内容,不转义 writer.WriteRawValue(jsonString); } else { writer.WriteNull(); } } }
在实体类字段上应用特性:
public class ObjectToSerialize { public string Identifier { get; set; } [JsonConverter(typeof(RawJsonConverter))] public string JsonPayload { get; set; } public ObjectToSerialize() { Identifier = string.Empty; JsonPayload = string.Empty; } }
情况2:使用System.Text.Json(ASP.NET Core 3.0+默认)
实现JsonConverter<string>类:
using System.Text.Json; using System.Text.Json.Serialization; public class RawStringJsonConverter : JsonConverter<string> { public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 反序列化时读取原始字符串 return reader.GetString(); } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { if (!string.IsNullOrEmpty(value)) { // 写入原始JSON内容,不转义 writer.WriteRawValue(value); } else { writer.WriteNullValue(); } } }
在实体类字段上应用特性:
public class ObjectToSerialize { public string Identifier { get; set; } [JsonConverter(typeof(RawStringJsonConverter))] public string JsonPayload { get; set; } public ObjectToSerialize() { Identifier = string.Empty; JsonPayload = string.Empty; } }
内容的提问来源于stack exchange,提问作者roboblocky
相关产品推荐
相关产品推荐

