.NET 8下Swagger生成JSON时排除循环引用的通用方案咨询
解决.NET 8中Swagger因Newtonsoft.Json循环引用无法加载的问题
针对你遇到的.NET 8迁移后,Swagger因循环引用无法正常加载(Terraform脚本无法生成Swagger JSON进而无法同步到APIM),且无法移除循环引用、System.Text.Json的[JsonIgnore]不适用的情况,以下是几个通用解决方案:
方案1:自定义Swagger Schema过滤器排除循环引用属性
直接在Swagger生成Schema的阶段排除指定的循环引用属性,不依赖JSON序列化库的配置,通用性最强。
实现步骤:
- 创建自定义Schema过滤器类:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; public class ExcludeCircularReferenceFilter : ISchemaFilter { private readonly string[] _propertiesToExclude; public ExcludeCircularReferenceFilter(params string[] propertiesToExclude) { _propertiesToExclude = propertiesToExclude; } public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema.Properties == null || _propertiesToExclude.Length == 0) return; foreach (var propName in _propertiesToExclude) { if (schema.Properties.ContainsKey(propName)) { schema.Properties.Remove(propName); } } } }
- 在Program.cs中注册该过滤器,指定要排除的循环引用属性(比如你的
NextForecast):
var builder = WebApplication.CreateBuilder(args); // 保留原有服务配置,确保添加Newtonsoft.Json支持 builder.Services.AddControllers().AddNewtonsoftJson(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { // 添加自定义过滤器,排除NextForecast属性 c.SchemaFilter<ExcludeCircularReferenceFilter>("NextForecast"); }); var app = builder.Build(); // 后续中间件配置不变 if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
方案2:让Swagger遵循Newtonsoft.Json的序列化规则
如果团队坚持使用Newtonsoft.Json,可配置SwaggerGen使用Newtonsoft的ContractResolver,这样Swagger会识别Newtonsoft的[JsonIgnore]注解,同时也能处理循环引用的序列化配置。
实现步骤:
- 确保项目已安装
Swashbuckle.AspNetCore.Newtonsoft包,然后在Program.cs中配置:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddNewtonsoftJson(options => { // 配置Newtonsoft.Json处理循环引用(可选,根据需求选择) options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // 也可使用序列化+保留引用的方式 // options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects; }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { // 配置Swagger使用Newtonsoft的ContractResolver c.UseAllOfToExtendReferenceSchemas(); c.UseNewtonsoftJson(); }); var app = builder.Build(); // 中间件配置不变 // ...
配置后,WeatherForecast类中的[JsonIgnore]注解会被Swagger识别,生成Schema时会排除NextForecast属性,同时Newtonsoft的循环引用配置也会生效。
方案3:使用Swashbuckle专属注解隐藏属性
直接使用Swashbuckle提供的注解控制Schema生成,和JSON序列化库解耦:
在循环引用属性上添加[SwaggerSchema(Hidden = true)]注解(需引用Swashbuckle.AspNetCore.Annotations包):
using Swashbuckle.AspNetCore.Annotations; using Newtonsoft.Json; namespace CircularReferenceFix; public class WeatherForecast { // 其他属性不变 // ... // 用Swashbuckle注解隐藏该属性,排除出Swagger Schema [SwaggerSchema(Hidden = true)] public WeatherForecast NextForecast { get; set; } }
然后在Program.cs的SwaggerGen配置中启用注解支持:
builder.Services.AddSwaggerGen(c => { c.EnableAnnotations(); });
以上方案都能解决Swagger因循环引用无法加载的问题,你可以根据团队的技术栈和需求选择最合适的方式。
内容的提问来源于stack exchange,提问作者Kristaps L
相关产品推荐
相关产品推荐

