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

9bfwbjaz  于 2023-04-20  发布在  其他
关注(0)|答案(1)|浏览(144)

我已经在我的AspNetCore2.1应用程序中实现了Swagger/Swashbuckle,它运行得很好。然而,我的一些API模型基于复杂的WCF XML服务,并使用一些System.Xml.Serialization注解来添加名称空间和更改属性名称。当在Swagger页面上查看这些模型时,它们会丢失名称空间并忽略任何属性名称更改。因此,Swagger默认请求将不会被调用。t在发布到我的控制器时反序列化。另一方面,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请求模式(我甚至不知道它们是否是-或者可以是-分开的).我以为这会很简单,但我迷失了swashbuckle选项和设置的海洋.我希望我可以简单地分配aspnet xml序列化器来反序列化提供的请求对象.或者实现ISchemaFilter或IOperationsFilter?
如果有人能给我指明正确的方向,我将永远感激。

lf5gs5x2

lf5gs5x21#

好吧,我自己回答。
我最终实现了ISchemaFilter。所以为了使用与问题中相同的模型来回答这个问题,我首先创建了自己的ISchemaFilter实现,并在检查中硬编码了所需的更改(实际上我将有一个大字典〈〉的类和属性更改)。“Schema”类允许我们仅向模型类或其任何属性添加XML meta。

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服务配置调用中连接这个过滤器。

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 prop不支持多个命名空间。在任何情况下,只要我不使用这些命名空间,XML反序列化就可以正常进行。如果我添加带有命名空间的属性,然后将它们设置为根元素的Attributes(Xml prop确实处理了),我可能可以添加它们。尽管还没有尝试过。

相关问题