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

Swashbuckle.AspNetCore.SwaggerGen v5中如何获取JsonContract?

在Swashbuckle.AspNetCore.SwaggerGen v5版本中获取JsonContract的方案

背景

在Swashbuckle.AspNetCore.SwaggerGen v4.0.1.0版本中,实现了如下ISchemaFilter用于将非可空值类型属性标记为必填:

public class RequireNonNullableValueTypePropertiesSchemaFilter : ISchemaFilter
{
    public void Apply(Schema schema, SchemaFilterContext context)
    {
        if (schema.Type == "object" && context.JsonContract is JsonObjectContract jsonObjectContract)
        {
            var valueTypeProperties = jsonObjectContract.Properties
                                                .Where(property => property.PropertyType.IsValueType)
                                                .Where(property => !property.PropertyType.IsGenericType || property.PropertyType.GetGenericTypeDefinition() != typeof(Nullable<>))
                                                .Select(property => property.PropertyName)
                                                .ToList();
            if (valueTypeProperties.Count > 0)
            {
                if (schema.Required == null)
                {
                    schema.Required = new List<string>();
                }
                foreach (var valueTypeProperty in valueTypeProperties.Except(schema.Required))
                {
                    schema.Required.Add(valueTypeProperty);
                }
            }
        }
    }
}

升级至v5版本后,SchemaFilterContext移除了JsonContract属性,导致原代码中的核心判断逻辑失效。经过一周调研和尝试(因项目架构限制无法在DLL中调试断点),仍未找到替代方案。

项目架构信息:

  • 解决方案包含多个服务契约类库(ServiceContract1、ServiceContract2等)
  • 所有契约类库依赖同一个ServiceExtensions类库
  • 契约类库发布为NuGet包,由外部控制台应用加载
  • 外部控制台应用通过加载这些NuGet包生成Swagger文档

解决方案

在v5版本中,SchemaFilterContext提供了SerializerOptions属性,可通过该属性获取配置的契约解析器,进而获取目标类型的JsonContract。重构后的代码如下:

using Newtonsoft.Json.Serialization;

public class RequireNonNullableValueTypePropertiesSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        // v5版本中Schema已替换为OpenApiSchema
        if (schema.Type == "object" && context.Type != null)
        {
            // 从SerializerOptions中获取JsonSerializerSettings及契约解析器
            var jsonSettings = context.SerializerOptions as JsonSerializerSettings;
            if (jsonSettings?.ContractResolver == null) return;

            var jsonContract = jsonSettings.ContractResolver.ResolveContract(context.Type);
            if (jsonContract is not JsonObjectContract jsonObjectContract) return;

            var valueTypeProperties = jsonObjectContract.Properties
                .Where(p => p.PropertyType.IsValueType)
                .Where(p => !p.PropertyType.IsGenericType || p.PropertyType.GetGenericTypeDefinition() != typeof(Nullable<>))
                .Select(p => p.PropertyName)
                .ToList();

            if (valueTypeProperties.Count == 0) return;

            // v5版本中Required属性类型为HashSet<string>
            schema.Required ??= new HashSet<string>();
            foreach (var propertyName in valueTypeProperties.Except(schema.Required))
            {
                schema.Required.Add(propertyName);
            }
        }
    }
}

关键调整说明

  1. 类型替换:v5版本中Schema类已被OpenApiSchema替代,需同步修改方法参数类型。
  2. Required属性类型变更:原List<string>改为HashSet<string>,使用??=简化初始化逻辑。
  3. 获取JsonContract的新方式:通过context.SerializerOptions转换为JsonSerializerSettings,再利用ContractResolver.ResolveContract方法获取目标类型的契约。
  4. 空值判断优化:使用C# 8.0+的is not和空合并运算符简化代码逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:50:40