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

如何在不引用MVC包的扩展方法中注册JsonConverter供WebApi使用?

问题场景与解决方案

核心问题

在DDD分层项目中,自定义JsonConverter位于无法引用MVC包的项目中,如何通过扩展方法注册该转换器,使其在WebApi的响应序列化中生效,同时避免在Web项目的AddControllers中直接硬编码配置?

可行方案

方案一:拆分配置逻辑,隔离MVC依赖

这种方式既保持转换器所在项目的无MVC依赖特性,又能让Web项目轻松集成配置:

  1. 在转换器所在项目(无MVC引用):
    定义仅依赖System.Text.Json的静态方法,负责添加自定义转换器:

    using System.Text.Json;
    using System.Text.Json.Serialization;
    
    public static class JsonConverterSetup
    {
        // 仅负责添加转换器,不涉及任何MVC类型
        public static JsonSerializerOptions AddAliasConverters(this JsonSerializerOptions options)
        {
            options.Converters.Add(new AliasConverter());
            return options;
        }
    }
    
    // 自定义转换器实现(仅依赖System.Text.Json)
    public class AliasConverter : JsonConverter<IAlias>
    {
        public override IAlias Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            using var doc = JsonDocument.ParseValue(ref reader);
            var kind = doc.RootElement.GetProperty("Kind").GetString();
            
            return kind switch
            {
                nameof(AliasKind.Foo) => JsonSerializer.Deserialize<FooAlias>(doc.RootElement.GetRawText(), options),
                nameof(AliasKind.Relationship) => JsonSerializer.Deserialize<BarAlias>(doc.RootElement.GetRawText(), options),
                _ => throw new JsonException($"未知AliasKind类型: {kind}")
            };
        }
    
        public override void Write(Utf8JsonWriter writer, IAlias value, JsonSerializerOptions options)
        {
            // 序列化时按对象实际类型输出
            JsonSerializer.Serialize(writer, value, value.GetType(), options);
        }
    }
    
  2. 在Web项目(可引用MVC和转换器项目):
    在AddControllers的配置中调用上述静态方法,同时保持原有扩展方法的职责(仅注册服务):

    // Program.cs
    builder.Services.AddApplicationLayer(); // 仅注册领域/应用层服务,不涉及MVC配置
    
    builder.Services.AddControllers()
        .AddJsonOptions(opt =>
        {
            // 调用转换器项目中的配置方法,注入自定义转换器
            opt.JsonSerializerOptions.AddAliasConverters();
        });
    

方案二:利用DI配置选项实现自动注册

如果希望完全通过扩展方法自动完成配置,无需在Web项目中显式编写AddJsonOptions逻辑,可以借助IConfigureOptions接口:

  1. 在可引用MVC的项目(如Web项目或基础设施层):
    实现配置JsonOptions的逻辑:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Options;
    using System.Text.Json;
    
    public class JsonOptionsConfigurator : IConfigureOptions<JsonOptions>
    {
        public void Configure(JsonOptions options)
        {
            // 调用转换器项目中的配置方法
            options.JsonSerializerOptions.AddAliasConverters();
        }
    }
    
  2. 在扩展方法中注册配置类:
    在可引用MVC的项目中定义扩展方法,注册上述配置类:

    public static class DependencyInjection
    {
        public static IServiceCollection AddJsonConverterSetup(this IServiceCollection services)
        {
            services.ConfigureOptions<JsonOptionsConfigurator>();
            return services;
        }
    }
    
  3. 在Program.cs中调用扩展方法:

    builder.Services.AddApplicationLayer();
    builder.Services.AddJsonConverterSetup(); // 自动配置Json转换器
    builder.Services.AddControllers();
    

关键说明

  • 转换器本身仅依赖System.Text.Json,可以安全放在无MVC引用的项目中;
  • 配置JsonOptions的逻辑必须放在能引用MVC包的项目中(因为JsonOptions属于ASP.NET Core MVC的专用类型);
  • 两种方案都遵循了DDD的分层依赖原则,避免了跨层引用的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 01:45:06