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

.NET 8 Web API如何自定义Swagger的XDocument请求示例值?

问题描述

我用.NET 8编写了一个C# Web API的Post接口,代码如下:

[Route("/v1.0/Test/TestXmlCall")]
[Consumes("application/xml")]
[HttpPost]    
public async Task<IResult> TestXmlCall([FromBody][SwaggerTryItOutDefaultValue("<Test></Test>")] XDocument xml)
{
    var requestType = APIRequestType.ReportTable2;
    var acerTableType = AcerTableType.Table2;

    return await ReportNonStandardTrade(requestType, acerTableType);
}

接口能正常运行,但Swagger中显示的示例值是XDocument的完整结构描述,不是我预期的<Test></Test>。我尝试自定义了SwaggerTryItOutDefaultValue特性和对应的ISchemaFilter,代码如下:

public class SwaggerTryItOutDefaultValue : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.ParameterInfo != null)
        {
            var att = context.ParameterInfo.GetCustomAttribute<SwaggerTryItOutDefaultValueAttribute>();
            if (att != null)
            {
                schema.Example = new Microsoft.OpenApi.Any.OpenApiString(att.Value.ToString());
            }
        }
    }
}

public class SwaggerTryItOutDefaultValueAttribute : Attribute
{
    public string Value { get; }

    public SwaggerTryItOutDefaultValueAttribute(string value)
    {
        Value = value;
    }
}

但这种方式并未成功修改Swagger中的示例值,请问有没有可行的解决方法?

解决方案

方法1:调整SchemaFilter逻辑,适配XDocument类型

现有SchemaFilter失效的原因大概率是context.ParameterInfo在处理FromBody参数时无法正确获取,或者Swashbuckle对XDocument的Schema生成有特殊逻辑。可以修改SchemaFilter,直接清理默认生成的属性并指定示例:

public class SwaggerTryItOutDefaultValue : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        // 从参数上获取自定义特性
        var paramAttribute = context.ParameterInfo?.GetCustomAttribute<SwaggerTryItOutDefaultValueAttribute>();
        if (paramAttribute != null)
        {
            // 清除XDocument默认生成的复杂属性
            schema.Properties.Clear();
            // 指定类型为字符串、格式为XML
            schema.Type = "string";
            schema.Format = "xml";
            // 设置示例值
            schema.Example = new OpenApiString(paramAttribute.Value);
            return;
        }

        // 兼容类型上的特性(如果后续用到模型类)
        var typeAttribute = context.Type.GetCustomAttribute<SwaggerTryItOutDefaultValueAttribute>();
        if (typeAttribute != null)
        {
            schema.Properties.Clear();
            schema.Type = "string";
            schema.Format = "xml";
            schema.Example = new OpenApiString(typeAttribute.Value);
        }
    }
}

记得在Program.cs中注册这个Filter:

builder.Services.AddSwaggerGen(c =>
{
    c.SchemaFilter<SwaggerTryItOutDefaultValue>();
});

方法2:用IDocumentFilter直接修改目标接口的请求示例

如果SchemaFilter还是不生效,可以直接定位到目标接口,修改它的请求示例配置:

public class XmlExampleDocumentFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // 找到目标接口的路径
        if (swaggerDoc.Paths.TryGetValue("/v1.0/Test/TestXmlCall", out var pathItem) && pathItem.Post != null)
        {
            var requestBody = pathItem.Post.RequestBody;
            if (requestBody != null && requestBody.Content.TryGetValue("application/xml", out var mediaType))
            {
                // 设置XML示例值
                mediaType.Example = new OpenApiString("<Test></Test>");
                // 调整Schema为字符串类型,避免显示XDocument结构
                mediaType.Schema.Type = "string";
                mediaType.Schema.Format = "xml";
                mediaType.Schema.Properties.Clear();
            }
        }
    }
}

注册这个DocumentFilter:

builder.Services.AddSwaggerGen(c =>
{
    c.DocumentFilter<XmlExampleDocumentFilter>();
});

方法3:改用强类型模型替代XDocument(推荐)

如果业务允许,定义强类型的XML模型,不仅能让Swagger自动生成更友好的示例,还能获得类型安全的好处。可以配合Swashbuckle.AspNetCore.Filters包自定义示例:

  1. 先安装包:
Install-Package Swashbuckle.AspNetCore.Filters
  1. 定义XML模型和示例提供类:
[XmlRoot("Test")]
[Example(typeof(TestModelExample))]
public class TestModel
{
    // 根据实际需求添加XML属性或元素
}

public class TestModelExample : IExamplesProvider<TestModel>
{
    public TestModel GetExamples()
    {
        // 返回构造好的示例对象,Swagger会自动序列化为XML
        return new TestModel();
    }
}
  1. 修改接口参数:
[Route("/v1.0/Test/TestXmlCall")]
[Consumes("application/xml")]
[HttpPost]    
public async Task<IResult> TestXmlCall([FromBody] TestModel xml)
{
    // 将强类型模型转换为XDocument处理
    var xDoc = new XDocument();
    using var writer = XmlWriter.Create(xDoc.CreateWriter());
    new XmlSerializer(typeof(TestModel)).Serialize(writer, xml);
    
    var requestType = APIRequestType.ReportTable2;
    var acerTableType = AcerTableType.Table2;

    return await ReportNonStandardTrade(requestType, acerTableType);
}
  1. 注册示例Filter:
builder.Services.AddSwaggerGen(c =>
{
    c.ExampleFilters();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:04:59