none
Помогите разобраться в ошибке связанной с работой WCF и внешенго сервиса RRS feed

  • Вопрос

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

    К проекту Visual Studio подключаем Service References (http://online.moysklad.ru/ws/mutualSettlement?wsdl)

    Указанный сервис предоставляет два метода, возвращающих массивы разных типов данных. Но при обращении к одному из методов WCF пытается десериализовать ответ сервера для одного метода в тип другого метода. Проблема, скорее всего, связана с namespace'ами, но где именно нужно поправить и что? Бъемся над данной проблемой уже долго, пытались разместить методы отдельно (сделали так для одного из сервисов), но это очень криво выглядит и явно не выход. Помогите разобраться.



Ответы

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

    Вам нужно добавить Web Reference вместо ServiceReference и все заработает

    Вот ссылка, как добавить Web eference:http://crmbusiness.wordpress.com/2011/01/27/where-has-the-add-web-reference-button-gone-in-visual-studio-2010/

    Ваш код в тестовом приложении будет выглядеть вот так: (при правильных username and pass в консоли отобразится 230 000)

    MutualSettlementWS ws = new MutualSettlementWS();
                ws.Credentials = new NetworkCredential("username", "password");
                customer[] result = null;
                ws.customersBalanceList(DateTime.Now.AddDays(-20),
                                        DateTime.Now,
                                        "",
                                        "Ogrc_KVzglyWR32rtUm1l1",
                                        "",
                                        "",
                                        true,
                                        false, out result);
                result.ToList().ForEach(b => Console.WriteLine(b.finalBalance));




  • Это баг в WCF. Скорее всего wsdl mutualSettlement сервиса содержит аттрибуты, которые оказались не по зубам svcutil.exe. WCF сервис и обычный soap based web-service (например asmx сервис) генерируют разные wsdl.

    Если Вы посмотрите на  proxy класс сгенерированный svcutil, то увидите сл. строки:

     // CODEGEN: Parameter 'result' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlArrayAttribute'.
            [System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
            [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
            [System.ServiceModel.ServiceKnownTypeAttribute(typeof(entityTO))]
            [return: System.ServiceModel.MessageParameterAttribute(Name="result")]
            ConsoleApplication6.MutualSettlementService.balanceForCustomerResponse balanceForCustomer(ConsoleApplication6.MutualSettlementService.balanceForCustomer request);
            
            // CODEGEN: Parameter 'result' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlArrayAttribute'.
            [System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
            [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
            [System.ServiceModel.ServiceKnownTypeAttribute(typeof(entityTO))]
            
            [return: System.ServiceModel.MessageParameterAttribute(Name="result")]
            ConsoleApplication6.MutualSettlementService.customersBalanceListResponse customersBalanceList(ConsoleApplication6.MutualSettlementService.customersBalanceList request);
    
    Получается, что при парсинге SOAP ответа, WCF клиент пытается десериализовать XML тег "result" испрользуя первый метод у который помечен аттрибутом MessageParameterAttribute(Name="result")]. В Вашем случае это balanceForCustomerResponse, который содержит массив объектов типа operationHandle.
    4 июля 2012 г. 12:33

Все ответы

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

    Вам нужно добавить Web Reference вместо ServiceReference и все заработает

    Вот ссылка, как добавить Web eference:http://crmbusiness.wordpress.com/2011/01/27/where-has-the-add-web-reference-button-gone-in-visual-studio-2010/

    Ваш код в тестовом приложении будет выглядеть вот так: (при правильных username and pass в консоли отобразится 230 000)

    MutualSettlementWS ws = new MutualSettlementWS();
                ws.Credentials = new NetworkCredential("username", "password");
                customer[] result = null;
                ws.customersBalanceList(DateTime.Now.AddDays(-20),
                                        DateTime.Now,
                                        "",
                                        "Ogrc_KVzglyWR32rtUm1l1",
                                        "",
                                        "",
                                        true,
                                        false, out result);
                result.ToList().ForEach(b => Console.WriteLine(b.finalBalance));




  • Не забудьте отметить ответ, если он решит вашу проблему. Спасибо


    Для связи [mail]

    Модератор
  • Спасибо, Александр! Вы мне очень помогли.

    Только вот почему же через WCF не получилось?

  • Это баг в WCF. Скорее всего wsdl mutualSettlement сервиса содержит аттрибуты, которые оказались не по зубам svcutil.exe. WCF сервис и обычный soap based web-service (например asmx сервис) генерируют разные wsdl.

    Если Вы посмотрите на  proxy класс сгенерированный svcutil, то увидите сл. строки:

     // CODEGEN: Parameter 'result' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlArrayAttribute'.
            [System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
            [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
            [System.ServiceModel.ServiceKnownTypeAttribute(typeof(entityTO))]
            [return: System.ServiceModel.MessageParameterAttribute(Name="result")]
            ConsoleApplication6.MutualSettlementService.balanceForCustomerResponse balanceForCustomer(ConsoleApplication6.MutualSettlementService.balanceForCustomer request);
            
            // CODEGEN: Parameter 'result' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'System.Xml.Serialization.XmlArrayAttribute'.
            [System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
            [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
            [System.ServiceModel.ServiceKnownTypeAttribute(typeof(entityTO))]
            
            [return: System.ServiceModel.MessageParameterAttribute(Name="result")]
            ConsoleApplication6.MutualSettlementService.customersBalanceListResponse customersBalanceList(ConsoleApplication6.MutualSettlementService.customersBalanceList request);
    
    Получается, что при парсинге SOAP ответа, WCF клиент пытается десериализовать XML тег "result" испрользуя первый метод у который помечен аттрибутом MessageParameterAttribute(Name="result")]. В Вашем случае это balanceForCustomerResponse, который содержит массив объектов типа operationHandle.
    4 июля 2012 г. 12:33
  • Спасибо за подробный ответ, всё встало на свои места.

    И все же, есть ли выход из этой ситуации? Можно ли заставить WCF отличать ответы? 

    4 июля 2012 г. 15:27