【问题标题】:AspNetCore Swagger/Swashbuckle how to modify xml schema requestsAspNetCore Swagger/Swashbuckle 如何修改 xml 架构请求
【发布时间】:2018-10-19 14:49:50
【问题描述】:

我已经在我的 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。 但是,swagger 示例请求显示为;

<?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?

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

【问题讨论】:

    标签: c# xml swagger swashbuckle


    【解决方案1】:

    好的,我自己来回答。
    确实最终实现了 ISchemaFilter。因此,为了使用与问题中相同的模型来回答这个问题,我首先创建了自己的 ISchemaFilter 实现,并在检查所需更改时进行了硬编码(实际上我将拥有一个包含类和属性的大字典变化)。 “Schema”类允许我们将仅 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 服务配置调用中连接这个过滤器。

    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 道具确实处理),我可能能够添加它们。不过没试过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多