我已经在我的 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?
如果有人能指出我正确的方向,我将永远感激不已。
好的,好吧,我会自己回答这个问题。
我 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 确实处理),我也许能够添加它们。虽然没试过。