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

如何在.NET Core 3.1中为属性级Newtonsoft JsonConverter注入依赖

解决方案

实现原理

默认JsonConverterAttribute会调用转换器的无参构造函数完成实例化,无法自动从DI容器获取依赖服务;你之前尝试的旧方案使用了已过时的MvcJsonOptions(仅适配ASP.NET Core 2.x),.NET Core 3.1默认使用System.Text.Json,启用Newtonsoft.Json后需使用MvcNewtonsoftJsonOptions做配置。

本方案通过自定义ContractResolver,在属性构建阶段检测指定转换器特性,直接从当前请求的DI容器中获取已经完成依赖注入的转换器实例赋值给对应属性,无需全局注册转换器,仅标注了对应特性的属性才会触发逻辑,完全匹配你的需求。

具体实现步骤

步骤1:注册基础服务

在Startup.cs的ConfigureServices方法中注册所需服务:

// 注册HttpContext访问器,用于获取当前请求的DI容器
services.AddHttpContextAccessor();
// 注册你的业务服务
services.AddScoped<IMyService, MyServiceImpl>();
// 注册自定义JsonConverter,生命周期可根据依赖服务调整
services.AddTransient<HelloWorldCustomConverter>();

步骤2:实现支持DI的ContractResolver

using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

public class DiSupportContractResolver : DefaultContractResolver
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public DiSupportContractResolver(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        // 读取属性上的JsonConverter特性
        var converterAttr = member.GetCustomAttribute<JsonConverterAttribute>();
        if (converterAttr == null) return property;

        // 匹配需要支持DI的转换器类型,多转换器可扩展多个判断分支
        if (converterAttr.ConverterType == typeof(HelloWorldCustomConverter))
        {
            // 从当前请求的服务容器中获取已注入完成的转换器实例
            var converter = _httpContextAccessor.HttpContext?.RequestServices.GetRequiredService<HelloWorldCustomConverter>();
            if (converter != null)
            {
                property.Converter = converter;
            }
        }
        return property;
    }
}

步骤3:配置Newtonsoft.Json选项

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;

public class DiJsonOptionsSetup : IConfigureOptions<MvcNewtonsoftJsonOptions>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public DiJsonOptionsSetup(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void Configure(MvcNewtonsoftJsonOptions options)
    {
        // 替换默认的ContractResolver
        options.SerializerSettings.ContractResolver = new DiSupportContractResolver(_httpContextAccessor);
    }
}

步骤4:注册配置到容器

在Startup.cs的ConfigureServices方法中补充配置注册,必须先启用Newtonsoft.Json:

services.AddControllers()
    // 启用Newtonsoft.Json(.NET Core 3.1默认使用System.Text.Json,需显式启用)
    .AddNewtonsoftJson();

// 注册自定义Json配置
services.AddSingleton<IConfigureOptions<MvcNewtonsoftJsonOptions>, DiJsonOptionsSetup>();

验证效果

你原有代码完全不需要修改:HelloWorldCustomConverter的依赖注入逻辑保留,MyClass的Details属性上的[JsonConverter(typeof(HelloWorldCustomConverter))]特性也无需修改,仅该属性会触发带DI注入的转换器逻辑,不会全局生效。

注意事项

  • 若存在多个需要支持DI的转换器,仅需在CreateProperty方法中补充对应类型判断即可
  • 若在非请求场景下(如后台任务)序列化对象,HttpContext为空,需手动创建DI Scope获取转换器实例,再手动指定到序列化设置的Converters集合中
  • 需确保已安装对应版本的Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet包

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:15:03