AspNetCore Swagger / Swashbuckle如何修改xml模式请求

时间:2018-10-19 14:49:51

标签: c# xml swagger swashbuckle

我已经在我的AspNetCore 2.1应用程序中实现了Swagger / Swashbuckle,并且运行良好。但是,我的一些API模型基于复杂的WCF XML服务,并使用一些System.Xml.Serialization注释来添加名称空间和更改属性名称。 在Swagger页面上查看这些模型时,它们缺少名称空间,并忽略任何属性名称更改。因此,迅速的默认请求在发布到我的控制器时不会反序列化。 另一方面,JSON请求可以正常工作。

考虑这两个类;

public class test
{
    [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.example.com/ns/v1")]
    public test_c ct1 { get; set; }
    public string t2 { get; set; }
}

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.example.com/ns/v1")]
public class test_c
{
    [System.Xml.Serialization.XmlElementAttribute("my-new-name")]
    public string tc1 { get; set; }
    public string tc2 { get; set; }
}

当序列化为XML时,我们得到类似的东西

<?xml version="1.0" encoding="UTF-8"?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ct1 xmlns="http://www.example.com/ns/v1">
        <my-new-name>aaa</my-new-name>
        <tc2>xxxxxx</tc2>
    </ct1>
    <t2>bbb</t2>
</test>

这是期望作为请求的xml。 但是,招摇的样本请求显示为;

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <ct1>
        <tc1>string</tc1>
        <tc2>string</tc2>
    </ct1>
    <t2>string</t2>
</test>

发布时不会反序列化。

现在到这一点。我需要/希望做的就是修改swagger请求xml模式-在不影响JSON请求模式的情况下(我什至不知道它们是-还是可以分开)。 我以为这很简单,但是我迷失了许多花哨的选项和设置。 我希望我可以简单地分配aspnet xml序列化程序来反序列化提供的请求对象。还是实现ISchemaFilter或IOperationsFilter?

如果有人可以指出正确的方向,我将永远感激不已。

1 个答案:

答案 0 :(得分:0)

好的,我自己回答。
did 最后实现了ISchemaFilter。因此,为了使用与问题相同的模型来回答此问题,我首先创建了自己的ISchemaFilter实现,并在检查中对所需的更改进行了硬编码(实际上,我将拥有一个很大的类和属性字典<>变化)。 “架构”类使我们可以将仅XML元数据添加到模型类或其任何属性。

public class MyRequestISchemaFilter : ISchemaFilter
{
    public void Apply(Schema schema, SchemaFilterContext context)
    {
        if (schema.Type == "object"){

            if (context.SystemType == typeof(test_c))
            {
                schema.Xml = new Xml()
                {
                    Namespace = "http://www.example.com/ns/v1"
                };
                foreach (var prop in schema.Properties)
                {
                    if (prop.Key == "tc1")
                    {
                        prop.Value.Xml = new Xml()
                        {
                            Name = "my-new-name"
                        };
                    }
                }
            }
        }
    }
}

然后在启动时在AddSwaggerGen服务configure调用中连接此过滤器。

services.AddSwaggerGen(c =>
{
    c.SchemaFilter<MyRequestISchemaFilter>();
    ...

这是过滤器将生成的示例请求XML;

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <ct1 xmlns="http://www.example.com/ns/v1">
        <my-new-name>string</my-new-name>
        <tc2>string</tc2>
    </ct1>
    <t2>string</t2>
</test>

它缺少根级XMLSchema名称空间,但是Schema :: Xml属性不支持多个名称空间。在任何情况下,只要我不使用这些名称空间,XML都可以反序列化。 如果添加带有名称空间的属性,然后将它们设置为根元素的属性(Xml prop会处理),则可以添加它们。还没尝试过。