none
WCF. MessageContract генерит не верное SOAP сообщение для вложенного типа. RRS feed

  • Общие обсуждения

  • Добрый день.

    У вложенного типа namespace выставляется namespace сборки, а не то, что я указал. Вот код формируемого SOAP сообщения, чтобы было сразу понятно о чем речь:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
    ...
    </s:Header>
    <s:Body>
    <BoolValue xmlns="http://my.site/rev2015">true</BoolValue>
    <StringValue xmlns="http://my.site/rev2015">HelloWorld</StringValue>
    <InnerType xmlns="http://my.site/rev2015" xmlns:a="http://schemas.datacontract.org/2004/07/Server" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <a:ANotherBool>true</a:ANotherBool>
    <a:AnotherStringValue>AnotherHelloWorld</a:AnotherStringValue>
    </InnerType>
    </s:Body>
    </s:Envelope>

    a:AnotherBool, a: AnotherStringValue - это не верно. Должно было быть "http://my.site/rev2015" !

    Интересно, что вот для самого InnerType namespace прописан верно. А вот для его вложенных свойств уже нет.

    Вот какой код использую:

    [ServiceContract(Namespace = "http://my.site/rev2015")]
    [ServiceKnownType(typeof(InnerType))]
    public interface IService1
    {
        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);
    }
    
    [MessageContract(WrapperNamespace = "http://my.site/rev2015", IsWrapped = false)]
    public class CompositeType
    {
        [MessageBodyMember(Namespace = "http://my.site/rev2015")]
        public bool BoolValue;
        [MessageBodyMember(Namespace = "http://my.site/rev2015")]
        public string StringValue;
        [MessageBodyMember(Namespace = "http://my.site/rev2015")]
        public InnerType InnerType;
    }
    
    [MessageContract(WrapperNamespace = "http://my.site/rev2015", IsWrapped = false)]
    public class InnerType
    {
        [MessageBodyMember(Namespace = "http://my.site/rev2015")]
        public bool ANotherBool;
        [MessageBodyMember(Namespace = "http://my.site/rev2015")]
        public string AnotherStringValue;
    }
    
    // impl
    [ServiceBehavior(Namespace = "http://my.site/rev2015")]
    public class Service1 : IService1
    {
        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {...}
    }

    Такой формат сообщения не моя хотелка. Так требует СМЭВ (тут их инструмент валидации сообщений http://smev.gosuslugi.ru/portal/services-tools.jsp). 

    Подскажите пожалуйста, как побороть такую странность.

    [UPD]. Добавлю еще одно примечание:

    IsWrapped = true

    Не подойдет. Т.к. требование к MessageContract заключается в том, что входной параметр функции ДОЛЖЕН быть один. 

    А спецификация СМЭВ требует, чтобы в элементе s:Body находилось два под-элемента Message и MessageDta. 

    К тому же с таким флагом появляется лишний уровень вложенности в SOAP, что, очевидно, не подходит СМЭВ.

    16 февраля 2015 г. 16:34

Все ответы