ServiceStack пытается связать классы закрытых полей, созданные с помощью ссылки на службу, а не из открытых свойств - PullRequest
0 голосов
/ 16 ноября 2018

Существует удаленная служба, которую я пытаюсь заставить отправлять мне сообщения через запросы HTTP POST с использованием SOAP. Я генерировал сервисные DTO, используя встроенную в Visual Studio опцию «Добавить сервисную ссылку».

Вот пример одного автоматически сгенерированного класса:

[Route("/test", "POST")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, 
Namespace="http://www.reservationassistant.com/Booking/Types")]
public partial class UpdateBookingRequest
{

private Booking bookingField;

private string resortIdField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public Booking Booking
{
    get
    {
        return this.bookingField;
    }
    set
    {
        this.bookingField = value;
    }
}

Когда я создаю свои методы ServiceInterface и запускаю свой сервис, чтобы перейти на страницу метаданных, я получаю этот пример SOAP-сообщения

<UpdateBookingRequest>
  <bookingField>
         ....
  <bookingField>
<UpdateBookingRequest>

это код в моем классе интерфейса обслуживания:

UpdateBookingResponse Post(UpdateBookingRequest request)
{
    // do stuff with request
    return null;
}

Как вы, вероятно, подразумеваете под автоматически сгенерированным классом, сообщения, которые я получаю, будут иметь имена тегов, равные публичным свойствам в сгенерированных DTO. Однако это никогда не будет возможно, поскольку по какой-то причине ServiceStack пытается связать элементы входящего сообщения XML с частными полями DTO (пример сообщения SOAP, сгенерированного страницей метаданных моей службы, - обратите внимание на постфикс «field» после «booking» «). Как сделать так, чтобы входящие сообщения связывались с общими свойствами, а не с частными полями?

1 Ответ

0 голосов
/ 16 ноября 2018

Во-первых, если вам нужны Typed C # Services, я настоятельно рекомендую использовать более гибкую, универсальную, более чистую и быструю альтернативу в C # Add ServiceStack Reference .SOAP - это медленный, хрупкий и раздутый формат сериализации , который следует рассматривать только для устаревших интеграций.

По умолчанию ServiceStack использует .NET XML DataContract Serializer для сериализации XML или SOAP, поэтому поведение зависитв .NET XML DataContractSerializer реализация.

Для обработки SOAP он использует общий класс Message WCF, который по умолчанию использует DataContractSerializer, но вы можете переключиться на заполнение WCF Message, используя реализацию XmlSerializer, добавив Атрибут [XmlSerializerFormat] в ваших DTO для запросов и ответов.

Вы можете запросить WCF svcutil в .NET для принудительной генерации классов DataContract или XmlSerializer с помощью командной строки /serializerпереключатель, например:

svcutil endpoint.wsdl /serializer:DataContractSerializer
svcutil endpoint.wsdl /serializer:XmlSerializer

Переопределение ContentTypes

Вы можете зарегистрировать пользовательский тип содержимого для переопределения сериализации Xml, используемой для запросов XML, например, вы можете переопределить ее для использованияXmlSerializer реализация для обработки запросов XML с чем-то вроде:

ContentTypes.Register(MimeTypes.Xml,
    (req, dto, stream) => {
        using (var xw = XmlWriter.Create(stream))
        {
            var ser = new XmlSerializerWrapper(dto.GetType());
            ser.WriteObject(xw, dto);
        }
    },
    (type, stream) => {
        using (var reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()))
        {
            var serializer = new System.Xml.Serialization.XmlSerializer(type);
            return serializer.Deserialize(reader);
        }                    
    });

Metadata Предварительный просмотр для запросов SOAP

Поскольку вы выводите поведение из предварительного просмотра метаданных, обратите внимание, что предварительный просмотр не генерируется с использованием WCF Serializer для запросов SOAP, тело запроса генерируется с использованием DataContraceSerializer, поэтомуне будет отражать тот же вывод при использовании реализации XmlSerializer в сообщении WCF.

...