Asp.net web api Swashback没有为数组\list属性正确生成示例xml

Asp.net web api Swashback没有为数组\list属性正确生成示例xml,asp.net-web-api,swashbuckle,Asp.net Web Api,Swashbuckle,当模型具有列表属性时,Swashback\swagger ui(5.6-使用swagger ui)似乎无法正确生成示例XML 要查看此问题: 1-创建一个空的webapi项目(我正在使用asp.net) 2-添加两个示例模型(我使用客户+订单进行测试) 4-更改web api配置以允许简单XML public static class WebApiConfig { public static void Register(HttpConfiguration config) {

当模型具有列表属性时,Swashback\swagger ui(5.6-使用swagger ui)似乎无法正确生成示例XML

要查看此问题:

1-创建一个空的webapi项目(我正在使用asp.net)

2-添加两个示例模型(我使用客户+订单进行测试)

4-更改web api配置以允许简单XML

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Formatters.XmlFormatter.UseXmlSerializer = true;  //ADD THIS
    }
}
5-运行站点并使用/swagger ui将参数内容类型更改为xml并选择示例模型。您会发现示例如下所示

<?xml version="1.0"?>
<Customer>
  <AccountNumber>string</AccountNumber>
  <Orders>
    <OrderNumber>string</OrderNumber>
  </Orders>
</Customer>

一串
一串
6-在控制器的customer.ToString()行上使用断点提交此命令,您将发现Orders集合为空

7-将swagger ui中的XML修改为以下内容并提交:

<?xml version="1.0"?>
<Customer>
  <AccountNumber>string</AccountNumber>
  <Orders>
    <Order><OrderNumber>string</OrderNumber></Order>
  </Orders>
</Customer>

一串
一串
8-现在已正确填充
Customer.Orders
集合

在Swashback中修复或解决此问题的最佳方法是什么


(关于这一点有一些讨论,以及它是swagger ui中的bug还是Swashback中的bug,但我对使用Swashback解决它特别感兴趣)

我发现了以下工作:

1-添加ISchemaFilter的实现

internal class ApplySchemaVendorExtensions : ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        // Fix issues with xml array examples not generating correctly
        if (!type.IsValueType)
        {
            schema.xml = new Xml { name = type.Name };
            if(schema.properties != null)
            {
                foreach (var property in schema.properties)
                {
                    //Array property, which wraps its elements
                    if (property.Value.type == "array")
                    {
                        property.Value.xml = new Xml
                        {
                            name = $"{property.Key}",
                            wrapped = true
                        };
                    }
                }
            }
        }
    }
}
2-将此行注释到SwaggerConfig.cs中

c.SchemaFilter<ApplySchemaVendorExtensions>();
c.SchemaFilter();
重复问题中的测试,示例XML现在可以直接工作。和往常一样,我很好奇是否有更好的解决方案


编辑:实际上,这在原始项目中很奇怪,我有这个问题,但在这个问题的小复制项目中,它的行为略有不同!当我找到原因时,我将编辑此答案。

我发现了以下作品:

1-添加ISchemaFilter的实现

internal class ApplySchemaVendorExtensions : ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        // Fix issues with xml array examples not generating correctly
        if (!type.IsValueType)
        {
            schema.xml = new Xml { name = type.Name };
            if(schema.properties != null)
            {
                foreach (var property in schema.properties)
                {
                    //Array property, which wraps its elements
                    if (property.Value.type == "array")
                    {
                        property.Value.xml = new Xml
                        {
                            name = $"{property.Key}",
                            wrapped = true
                        };
                    }
                }
            }
        }
    }
}
2-将此行注释到SwaggerConfig.cs中

c.SchemaFilter<ApplySchemaVendorExtensions>();
c.SchemaFilter();
重复问题中的测试,示例XML现在可以直接工作。和往常一样,我很好奇是否有更好的解决方案


编辑:实际上,这在原始项目中很奇怪,我有这个问题,但在这个问题的小复制项目中,它的行为略有不同!感谢@mutex,我将在找到原因后编辑此答案,但我发现我需要对其进行另一次调整:

internal class SwaggerFixArraysInXmlFilter : Swashbuckle.Swagger.ISchemaFilter
{
    // this fixes a Swagger bug that wasn't generating correct XML elements around List<> or array[] types
    public void Apply(Swashbuckle.Swagger.Schema schema, Swashbuckle.Swagger.SchemaRegistry schemaRegistry, System.Type type)
    {
        // Fix issues with xml array examples not generating correctly
        if (!type.IsValueType)
        {
            schema.xml = new Swashbuckle.Swagger.Xml { name = type.Name };
            if (schema.properties != null)
            {
                foreach (var property in schema.properties)
                {
                    //Array property, which wraps its elements
                    if (property.Value.type == "array")
                    {
                        property.Value.xml = new Swashbuckle.Swagger.Xml
                        {
                            name = $"{property.Key}",
                            wrapped = true
                        };
                        property.Value.items.xml = new Swashbuckle.Swagger.Xml
                        {
                            name = $"{property.Value.items.type}",
                            wrapped = true
                        };
                    }
                }
            }
        }
    }
}
内部类swaggerfixarysinxmlfilter:swashback.Swagger.ISchemaFilter
{
//这修复了一个招摇过市的bug,该bug没有围绕列表或数组[]类型生成正确的XML元素
public void Apply(swashback.Swagger.Schema架构,swashback.Swagger.SchemaRegistry SchemaRegistry,System.Type)
{
//修复xml数组示例无法正确生成的问题
如果(!type.IsValueType)
{
schema.xml=new-swashback.Swagger.xml{name=type.name};
if(schema.properties!=null)
{
foreach(schema.properties中的var属性)
{
//数组属性,该属性包装其元素
if(property.Value.type==“数组”)
{
property.Value.xml=new swashback.Swagger.xml
{
名称=$“{property.Key}”,
包装=真
};
property.Value.items.xml=new swashback.Swagger.xml
{
名称=$“{property.Value.items.type}”,
包装=真
};
}
}
}
}
}
}

多亏了@mutex,但我发现我需要对它进行另一次调整:

internal class SwaggerFixArraysInXmlFilter : Swashbuckle.Swagger.ISchemaFilter
{
    // this fixes a Swagger bug that wasn't generating correct XML elements around List<> or array[] types
    public void Apply(Swashbuckle.Swagger.Schema schema, Swashbuckle.Swagger.SchemaRegistry schemaRegistry, System.Type type)
    {
        // Fix issues with xml array examples not generating correctly
        if (!type.IsValueType)
        {
            schema.xml = new Swashbuckle.Swagger.Xml { name = type.Name };
            if (schema.properties != null)
            {
                foreach (var property in schema.properties)
                {
                    //Array property, which wraps its elements
                    if (property.Value.type == "array")
                    {
                        property.Value.xml = new Swashbuckle.Swagger.Xml
                        {
                            name = $"{property.Key}",
                            wrapped = true
                        };
                        property.Value.items.xml = new Swashbuckle.Swagger.Xml
                        {
                            name = $"{property.Value.items.type}",
                            wrapped = true
                        };
                    }
                }
            }
        }
    }
}
内部类swaggerfixarysinxmlfilter:swashback.Swagger.ISchemaFilter
{
//这修复了一个招摇过市的bug,该bug没有围绕列表或数组[]类型生成正确的XML元素
public void Apply(swashback.Swagger.Schema架构,swashback.Swagger.SchemaRegistry SchemaRegistry,System.Type)
{
//修复xml数组示例无法正确生成的问题
如果(!type.IsValueType)
{
schema.xml=new-swashback.Swagger.xml{name=type.name};
if(schema.properties!=null)
{
foreach(schema.properties中的var属性)
{
//数组属性,该属性包装其元素
if(property.Value.type==“数组”)
{
property.Value.xml=new swashback.Swagger.xml
{
名称=$“{property.Key}”,
包装=真
};
property.Value.items.xml=new swashback.Swagger.xml
{
名称=$“{property.Value.items.type}”,
包装=真
};
}
}
}
}
}
}

如果您在Swagger v5中使用.Net Core 2.2,则需要以下代码集

internal class SwaggerFixArraysInXmlFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            Type type = context.Type;

            // Fix issues with xml array examples not generating correctly
            if (!type.IsValueType)
            {
                schema.Xml = new OpenApiXml { Name = type.Name };
                if (schema.Properties != null)
                {
                    foreach (var property in schema.Properties)
                    {
                        //Array property, which wraps its elements
                        if (property.Value.Type == "array")
                        {
                            property.Value.Xml = new OpenApiXml
                            {
                                Name = $"{property.Key}",
                                Wrapped = true
                            };
                            property.Value.Items.Xml = new OpenApiXml
                            {
                                Name = $"{property.Value.Items.Type}",
                                Wrapped = true
                            };
                        }
                    }
                }
            }
        }
    }

如果将.Net Core 2.2与Swagger v5一起使用,则需要以下代码集

internal class SwaggerFixArraysInXmlFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            Type type = context.Type;

            // Fix issues with xml array examples not generating correctly
            if (!type.IsValueType)
            {
                schema.Xml = new OpenApiXml { Name = type.Name };
                if (schema.Properties != null)
                {
                    foreach (var property in schema.Properties)
                    {
                        //Array property, which wraps its elements
                        if (property.Value.Type == "array")
                        {
                            property.Value.Xml = new OpenApiXml
                            {
                                Name = $"{property.Key}",
                                Wrapped = true
                            };
                            property.Value.Items.Xml = new OpenApiXml
                            {
                                Name = $"{property.Value.Items.Type}",
                                Wrapped = true
                            };
                        }
                    }
                }
            }
        }
    }

感谢@Abacus,但我发现我需要对它进行另一次调整。(String不是ValueType,因此它将任何字符串值重命名为String…可能与.NET Core 3.1有关)


感谢@Abacus,但我发现我需要对它进行另一次调整。(String不是ValueType,因此它将任何字符串值重命名为String…可能与.NET Core 3.1有关)


我认为这是,尽管你的描述与问题相匹配,但我比github问题更清楚。我认为这是,尽管你的描述与问题相匹配,但我比github问题更清楚。要完成上述解决方案,请使用Microsoft.OpenApi.Models添加以下用法:;使用Swa