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

ASP.NET Core 3迁移:System.Text.Json是否有JRaw等效替代方案?

解决ASP.NET Core 3中System.Text.Json替代Newtonsoft.Json JRaw的方案

我之前在迁移ASP.NET Core 2到3.x的项目时,刚好遇到过和你一模一样的问题——原来用Newtonsoft.Json的JRaw可以直接输出预格式化的JSON字符串,不用转义,但System.Text.Json不兼容JRaw,而且用JsonElement会额外做反序列化+序列化的操作,对大数据场景不友好。下面给你两种高效的解决方案,完全避免不必要的JSON解析:

方法一:自定义RawJson标记类+JsonConverter(推荐)

这个方案和JRaw的思路完全一致,通过自定义一个标记类来标识哪些属性是原始JSON,然后写对应的Converter直接把字符串写入输出流,不做任何解析:

1. 定义RawJsonString标记类

public class RawJsonString
{
    public string Value { get; }

    public RawJsonString(string value)
    {
        Value = value ?? throw new ArgumentNullException(nameof(value));
        // 可选:可以在这里加一个JSON合法性校验,避免写入无效JSON
        // JsonDocument.Parse(value);
    }
}

2. 实现对应的JsonConverter

public class RawJsonStringConverter : JsonConverter<RawJsonString>
{
    // 如果不需要反序列化该属性,可以跳过Read方法的实现(或者抛出NotImplementedException)
    public override RawJsonString Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var jsonDoc = JsonDocument.ParseValue(ref reader);
        return new RawJsonString(jsonDoc.RootElement.GetRawText());
    }

    public override void Write(Utf8JsonWriter writer, RawJsonString value, JsonSerializerOptions options)
    {
        // 核心:直接写入原始JSON内容,不转义、不解析
        writer.WriteRawValue(value.Value);
    }
}

3. 修改你的Thing类并使用

public class Thing 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    // 给Data属性添加Converter标记
    [JsonConverter(typeof(RawJsonStringConverter))]
    public RawJsonString Data { get; set; } 
}

// 实例化和序列化
var thing = new Thing 
{ 
    Id = 1, 
    Name = "Thing", 
    Data = new RawJsonString("{\"key\":\"value\"}") 
};

var json = JsonSerializer.Serialize(thing);
// 输出结果:{"Id":1,"Name":"Thing","Data":{"key":"value"}}

4. 全局注册(ASP.NET Core中)

如果你的项目中有很多地方需要用到这个功能,可以把Converter全局注册,不用每个属性都加标记:

services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new RawJsonStringConverter());
    });

方法二:直接使用Utf8JsonWriter手动序列化(适合临时场景)

如果只是个别地方需要处理,不想自定义类和Converter,可以直接用Utf8JsonWriter手动控制序列化过程:

using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream);

writer.WriteStartObject();
writer.WriteNumber("Id", thing.Id);
writer.WriteString("Name", thing.Name);
// 直接写入原始JSON
writer.WritePropertyName("Data");
writer.WriteRawValue(thing.Data);
writer.WriteEndObject();

writer.Flush();
var json = Encoding.UTF8.GetString(stream.ToArray());

为什么这个方案比JsonElement好?

  • 使用自定义Converter时,完全跳过了JSON的解析和重新序列化步骤,直接把原始字符串写入输出流,性能和JRaw几乎一致,非常适合大数据场景;
  • 而JsonElement需要先把字符串解析成DOM对象,序列化的时候再转成JSON,会额外消耗CPU和内存,数据越大差异越明显。

内容的提问来源于stack exchange,提问作者Jarru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:14:09