AspNetCore Swagger / Swashbuckle, как изменить запросы XML-схемы - PullRequest
0 голосов
/ 19 октября 2018

Я реализовал Swagger / Swashbuckle в своем приложении AspNetCore 2.1, и он отлично работает.Однако некоторые из моих моделей API основаны на сложных XML-сервисах WCF и используют несколько аннотаций 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>

, который не будет десериализоваться при публикации.

Так что теперь к сути.Все, что мне нужно / надеюсь сделать, - это изменить XML-схему запроса swagger, не затрагивая при этом схему запроса JSON (я даже не знаю, являются ли они или могут быть отдельными).Я думал, что это будет просто, но я потерял море опций и настроек.Я надеялся, что смогу просто назначить сериализатор aspnet xml для десериализации предоставленного объекта запроса.Или внедрить ISchemaFilter или IOperationsFilter?

Если бы кто-то мог указать мне правильное направление, я был бы всегда благодарен.

1 Ответ

0 голосов
/ 19 октября 2018

хорошо, я сам на это отвечу.
Я сделал в итоге реализовал 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 при запуске.

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).Хотя я этого не пробовал.

...