You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免已含有效JSON字符串的字段被重复序列化?

如何避免已含有效JSON的字段被重复序列化?

问题背景

我在ASP.NET中返回包含JSON字符串的对象列表时遇到了重复序列化的问题:

  1. 定义了从数据库读取数据的实体类:
public class ObjectToSerialize
{
    public string Identifier { get; set; }
    public string JsonPayload { get; set; }

    public ObjectToSerialize()
    {
        Identifier = string.Empty;
        JsonPayload = string.Empty;
    }
}
  1. 从数据库读取数据并填充列表:
List<ObjectToSerialize> listOfObjects = new List<ObjectToSerialize>();

// 省略数据库查询逻辑
while (sqlDataReader.Read())
{
    // 省略字段赋值逻辑
    listOfObjects.Add(new ObjectToSerialize());
}
  1. 通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:50:23