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

如何为Swagger示例实现分支逻辑以避免重复定义对象?

问题:如何为Swagger设置分支式示例,避免重复定义相同结构的对象?

我们插入的对象具备灵活性,原因是用户无法确定每个项所需的参数。这给确保Swagger展示前端开发人员所需信息带来了挑战。目前我正在定义一个结构完全一致、仅示例内容不同的对象,是否可以通过类似分支语句的方式设置示例,从而无需重复定义多个相同结构的对象?

当前代码实现:

[HttpPost("getsources")]
[ProducesResponseType(typeof(SourceMaterialResponse), StatusCodes.Status200OK)]
public ActionResult GetSources([FromBody] FilterSourceInput filters)
{ .... }

public class SourceMaterialResponse
{
    public bool success { get; set; }
    public string message { get; set; }

    /// <summary>
    /// 参数定义数组,格式为"列名": "值"
    /// </summary>
    /// <example>"Definition": "商业获取时的供应商名称"</example>
    public List<Parameter_Definition> parameters { get; set; }

    /// <summary>
    /// 来源数组,格式为"列名": "值"
    /// </summary>
    /// <example>{
    ///   "SourceID": "",
    /// "MaterialID": "",
    /// "Comments": "航空领域最常用的铝材",
    ///    "CeramicOrGlassReinforced": "",
    ///    "CeramicOrGlassComposition": "",
    ///    "PlasticElastomer": "",
    ///    "MaterialDescription": "这是一种以铜为主要合金元素的铝合金",
    ///    "PlasticComposition": "",
    ///    "OrganicPolymerCompositeCoreForm": "",
    ///    "NaturalType": "",
    ///    "OrganicPolymerCompositeMatrix": "",
    ///   "MaterialName": "Susan Alloy",
    ///    "MaterialClassOrType": "Metal",
    ///    "OrganicPolymerCompositeFiber": "",
    ///    "OrganicPolymerCompositeCore": "",
    ///    "MetalCompositionOrAlloy": "Copper"
    /// }</example>
    public List<Dictionary<string, string>> items { get; set; }
}

解决方案

可以通过自定义Swagger过滤器或扩展包实现动态示例切换,无需重复定义相同结构的对象,以下是两种实用方案:

方案1:自定义IOperationFilter实现动态示例

通过实现Swashbuckle的IOperationFilter接口,根据请求参数(如FilterSourceInput的字段值)动态替换Swagger响应示例。

步骤1:编写自定义过滤器

public class SourceMaterialResponseExampleFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // 获取请求中的FilterSourceInput参数元数据
        var filterParam = context.ApiDescription.ParameterDescriptions
            .FirstOrDefault(p => p.ParameterType == typeof(FilterSourceInput));

        if (filterParam == null) return;

        // 根据过滤器参数生成对应示例
        var responseExample = new OpenApiObject();
        // 这里从请求体解析参数,也可根据Query参数判断
        var filterModel = context.HttpContext.Request.Body.ReadFromJsonAsync<FilterSourceInput>().Result;
        var materialType = filterModel?.MaterialClassOrType;

        if (!string.IsNullOrEmpty(materialType) && materialType.Equals("Metal", StringComparison.OrdinalIgnoreCase))
        {
            // 金属材料示例
            responseExample["success"] = new OpenApiBoolean(true);
            responseExample["message"] = new OpenApiString("成功获取金属材料源");
            responseExample["parameters"] = new OpenApiArray
            {
                new OpenApiObject { ["Definition"] = new OpenApiString("商业获取时的供应商名称") }
            };
            responseExample["items"] = new OpenApiArray
            {
                new OpenApiObject
                {
                    ["SourceID"] = new OpenApiString("M001"),
                    ["MaterialName"] = new OpenApiString("Susan Alloy"),
                    ["MaterialClassOrType"] = new OpenApiString("Metal"),
                    ["MetalCompositionOrAlloy"] = new OpenApiString("Copper"),
                    ["MaterialDescription"] = new OpenApiString("以铜为主要合金元素的铝合金,广泛应用于航空领域")
                }
            };
        }
        else if (!string.IsNullOrEmpty(materialType) && materialType.Equals("Plastic", StringComparison.OrdinalIgnoreCase))
        {
            // 塑料材料示例
            responseExample["success"] = new OpenApiBoolean(true);
            responseExample["message"] = new OpenApiString("成功获取塑料材料源");
            responseExample["parameters"] = new OpenApiArray
            {
                new OpenApiObject { ["Definition"] = new OpenApiString("塑料材料的成分说明") }
            };
            responseExample["items"] = new OpenApiArray
            {
                new OpenApiObject
                {
                    ["SourceID"] = new OpenApiString("P001"),
                    ["MaterialName"] = new OpenApiString("航空级PC塑料"),
                    ["MaterialClassOrType"] = new OpenApiString("Plastic"),
                    ["PlasticComposition"] = new OpenApiString("聚碳酸酯"),
                    ["MaterialDescription"] = new OpenApiString("高强度耐冲击工程塑料,适用于航空内饰部件")
                }
            };
        }
        else
        {
            // 默认示例
            responseExample["success"] = new OpenApiBoolean(true);
            responseExample["message"] = new OpenApiString("成功获取材料源");
            responseExample["parameters"] = new OpenApiArray();
            responseExample["items"] = new OpenApiArray();
        }

        // 更新200响应的示例
        if (operation.Responses.TryGetValue("200", out var response))
        {
            response.Content["application/json"].Example = responseExample;
        }
    }
}

步骤2:注册过滤器

在Program.cs或Startup.cs中注册该过滤器:

builder.Services.AddSwaggerGen(c =>
{
    c.OperationFilter<SourceMaterialResponseExampleFilter>();
    // 其他Swagger配置(如读取XML注释)
});

方案2:使用Swashbuckle.AspNetCore.Filters包简化示例管理

通过第三方包Swashbuckle.AspNetCore.Filters可以更便捷地定义多组示例,再结合过滤器动态切换。

步骤1:安装包

Install-Package Swashbuckle.AspNetCore.Filters

步骤2:定义示例类

public class MetalSourceExample : IExamplesProvider<SourceMaterialResponse>
{
    public SourceMaterialResponse GetExamples()
    {
        return new SourceMaterialResponse
        {
            success = true,
            message = "成功获取金属材料源",
            parameters = new List<Parameter_Definition> { new() { Definition = "商业获取时的供应商名称" } },
            items = new List<Dictionary<string, string>>
            {
                new()
                {
                    ["SourceID"] = "M001",
                    ["MaterialName"] = "Susan Alloy",
                    ["MaterialClassOrType"] = "Metal",
                    ["MetalCompositionOrAlloy"] = "Copper",
                    ["MaterialDescription"] = "航空领域最常用的铝合金之一"
                }
            }
        };
    }
}

public class PlasticSourceExample : IExamplesProvider<SourceMaterialResponse>
{
    public SourceMaterialResponse GetExamples()
    {
        return new SourceMaterialResponse
        {
            success = true,
            message = "成功获取塑料材料源",
            parameters = new List<Parameter_Definition> { new() { Definition = "塑料材料成分说明" } },
            items = new List<Dictionary<string, string>>
            {
                new()
                {
                    ["SourceID"] = "P001",
                    ["MaterialName"] = "航空级PC塑料",
                    ["MaterialClassOrType"] = "Plastic",
                    ["PlasticComposition"] = "聚碳酸酯",
                    ["MaterialDescription"] = "高强度耐热工程塑料"
                }
            }
        };
    }
}

步骤3:结合过滤器动态选择示例

复用方案1的过滤器逻辑,在其中根据参数选择对应的示例类生成示例即可。


总结

  • 无需重复定义相同结构的对象,只需维护不同的示例数据
  • 自定义IOperationFilter灵活性最高,支持根据任意请求条件切换示例
  • Swashbuckle.AspNetCore.Filters可简化示例的组织和管理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:20:58