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

.NET 4.8下ASP.NET Web API替换Newtonsoft.Json为System.Text.Json的兼容改造问题

.NET 4.8下ASP.NET Web API替换Newtonsoft.Json为System.Text.Json的兼容改造问题

看起来你遇到的核心问题是:.NET 4.8的ASP.NET Web API默认依赖Newtonsoft.Json做模型绑定,哪怕你自己的Data类已经切换到System.Text.Json,Web API在反序列化请求体为Data.Request对象时,还是会用Newtonsoft,导致内部动态属性被反序列化成JObject而非你期望的JsonElement。

不用纠结于“为什么Newtonsoft还在参与”——这是Web API框架的默认行为,我们需要手动替换掉它的JSON格式化器,同时保持向后兼容性,下面是具体的落地步骤:

1. 准备依赖

首先在你的Web API项目中安装System.Text.Json NuGet包(选择兼容.NET Framework 4.8的版本,比如v6.0.x及以上,这些版本对4.8支持良好)。

2. 自定义System.Text.Json媒体格式化器

ASP.NET Web API通过MediaTypeFormatter处理请求/响应的序列化/反序列化,我们需要实现一个基于System.Text.Json的格式化器,替换掉默认的Newtonsoft实现:

using System.IO;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

public class SystemTextJsonMediaTypeFormatter : MediaTypeFormatter
{
    private readonly JsonSerializerOptions _serializerOptions;

    public SystemTextJsonMediaTypeFormatter(JsonSerializerOptions options = null)
    {
        // 配置序列化选项,尽量和原Newtonsoft行为对齐,保证向后兼容
        _serializerOptions = options ?? new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true, // 和Newtonsoft默认一致,忽略大小写匹配
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 按需调整,和原项目命名策略对齐
            WriteIndented = false, // 生产环境建议关闭缩进,和Newtonsoft默认一致
            Converters = { new JsonStringEnumConverter() } // 枚举序列化为字符串,对齐Newtonsoft默认行为
        };

        // 声明支持application/json媒体类型
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
        // 支持常用编码
        SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
        SupportedEncodings.Add(UnicodeEncoding.Unicode);
    }

    public override bool CanReadType(Type type) => true; // 支持所有类型的反序列化
    public override bool CanWriteType(Type type) => true; // 支持所有类型的序列化

    public override async Task<object> ReadFromStreamAsync(
        Type type, 
        Stream readStream, 
        HttpContent content, 
        IFormatterLogger formatterLogger)
    {
        using var reader = new StreamReader(readStream, SupportedEncodings.First());
        var jsonContent = await reader.ReadToEndAsync();
        return JsonSerializer.Deserialize(jsonContent, type, _serializerOptions);
    }

    public override async Task WriteToStreamAsync(
        Type type, 
        object value, 
        Stream writeStream, 
        HttpContent content, 
        TransportContext transportContext)
    {
        var jsonContent = JsonSerializer.Serialize(value, type, _serializerOptions);
        using var writer = new StreamWriter(writeStream, SupportedEncodings.First());
        await writer.WriteAsync(jsonContent);
    }
}

3. 替换Web API的默认格式化器

在Web API项目的Global.asax.cs的Application_Start方法中,替换默认的Newtonsoft格式化器为我们自定义的:

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);

    // 移除默认的Newtonsoft JSON格式化器
    var defaultJsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
    if (defaultJsonFormatter != null)
    {
        GlobalConfiguration.Configuration.Formatters.Remove(defaultJsonFormatter);
    }

    // 添加自定义的System.Text.Json格式化器
    GlobalConfiguration.Configuration.Formatters.Add(new SystemTextJsonMediaTypeFormatter());
}

4. 关键细节对齐(保证向后兼容)

为了让新旧客户端都能正常工作,需要确保System.Text.Json的序列化行为和原Newtonsoft完全对齐:

  • 命名策略:如果原项目用PascalCase(类属性默认的大写开头),就把PropertyNamingPolicy设为null;如果用驼峰,保持JsonNamingPolicy.CamelCase。
  • 空值处理:如果原Newtonsoft忽略空值属性,就在JsonSerializerOptions中设置DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull。
  • 特殊类型转换:如果有自定义类型的序列化逻辑,需要对应实现System.Text.Json的JsonConverter来替代原Newtonsoft的JsonConverter。

为什么这比“先反序列再重新序列化”更好?

你提到的临时方案(用Newtonsoft反序列后再转System.Text.Json)确实能凑活,但会带来双重序列化/反序列化的性能损耗,而且会让代码变得冗余难维护。替换格式化器是从框架层面解决问题,一次性搞定所有请求/响应的序列化逻辑,更干净也更高效。

兼容性验证

  • 新客户端(用System.Text.Json序列化请求):Web API用System.Text.Json反序列化,内部属性会是JsonElement,完全符合你的预期。
  • 旧客户端(用Newtonsoft序列化请求):只要JSON是标准格式(没有Newtonsoft特有的扩展比如$type),System.Text.Json就能正常反序列化,不会影响旧功能。
  • 响应兼容性:Web API用System.Text.Json序列化响应返回HttpResponseMessage,不管是新客户端用System.Text.Json还是旧客户端用Newtonsoft,都能正常解析标准JSON。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 10:34:33