AspNetCore Swagger/Swashbuckle如何修改xml schema请求

问题描述 投票:0回答:1

我已经在我的 AspNetCore 2.1 应用程序中实现了 Swagger/Swashbuckle,并且运行良好。然而,我的一些 API 模型基于复杂的 WCF XML 服务,并使用一些 System.Xml.Serialization 注释来添加命名空间和更改属性名称。 当在 Swagger 页面上查看这些模型时,它们缺少命名空间并忽略任何属性名称更改。因此,当发布到我的控制器时,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?

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

c# xml swagger swashbuckle
1个回答
2
投票

好的,好吧,我会自己回答这个问题。
did 最终实现了 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 prop 确实处理),我也许能够添加它们。虽然没试过。

© www.soinside.com 2019 - 2024. All rights reserved.