Вложенные элементы составного типа никогда не заполняются при вызове ОСНОВАННОГО НА ОСИ веб-сервиса от.NET

Я пытался в течение нескольких дней теперь получить клиент.NET, работающий полностью с веб-сервером, обеспеченным моим находящимся в Coldfusion веб-приложением. Я не разработчик.NET, по сути, но у меня, оказывается, есть копия VS 2003, который кажется, что должен добиться цели.

Я могу использовать простой множитель () метод в моем веб-сервисе, который берет два числа и возвращает число, таким образом, простые типы хорошо работают. Это - составные типы, которые уничтожают меня. Я в основном пытаюсь возвратить ассоциативный массив из метода, названного get_struct (). Я возвращаю объект Карты типа, но свойство (названный объектом), который, как предполагается, является массивом с двумя элементами (типа mapItem) всегда, имеет "неопределенное значение".

Вот WSDL, который сгенерирован ColdFusion:




 
  
   
   
   
   
    
   
   
    
     
     
    
   
  
  
   
   
   
   
    
     
     
    
   
   
    
     
    
   
  
  
   
   
   
   
    
     
      
     
    
   
   
    
     
      
     
    
   
  
 
   
      
   
   
      
   
   
      
   
   
      
   
   
   
   
      
         
   
      
   
   
      
         
         
         
      
      
         
         
         
      
      
         
         
         
      
   
   
      
      
         
         
            
         
         
            
         
         
            
         
      
      
         
         
            
         
         
            
         
         
            
         
      
      
         
         
            
         
         
            
         
         
            
         
      
   
   
  
This is a collection of test methods to allow remote developers
   to evaluate datatype support, etc in their programming environment.
   The WSDL endpoint for this web service is [YOUR PEERFOCUS SITE]/remote_api/pfapi/v/trunk/remote_io_test.cfc?wsdl  
      
         
      
   

и вот тупик веб-сервиса, сгенерированный, когда я добавляю веб-ссылку в VS:

//------------------------------------------------------------------------------
// 
//     This code was generated by a tool.
//     Runtime Version: 1.1.4322.2443
//
//     Changes to this file may cause incorrect behavior and will be lost if 
//     the code is regenerated.
// 
//------------------------------------------------------------------------------

// 
// This source code was auto-generated by Microsoft.VSDesigner, Version 1.1.4322.2443.
// 
namespace pfapi_test.remote_io_test {
    using System.Diagnostics;
    using System.Xml.Serialization;
    using System;
    using System.Web.Services.Protocols;
    using System.ComponentModel;
    using System.Web.Services;


    /// 
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Web.Services.WebServiceBindingAttribute(Name="remote_io_test.cfcSoapBinding", Namespace="http://trunk.v.pfapi.remote_api")]
    [System.Xml.Serialization.SoapIncludeAttribute(typeof(QueryBean))]
    [System.Xml.Serialization.SoapIncludeAttribute(typeof(CFCInvocationException))]
    public class remote_io_testService : System.Web.Services.Protocols.SoapHttpClientProtocol {

        /// 
        public remote_io_testService() {
            this.Url = "http://leon.cupahr.tafkan.nooch/remote_api/pfapi/v/trunk/remote_io_test.cfc";
        }

        /// 
        [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="http://trunk.v.pfapi.remote_api", ResponseNamespace="http://trunk.v.pfapi.remote_api")]
        [return: System.Xml.Serialization.SoapElementAttribute("multiplierReturn")]
        public System.Double multiplier(System.Double factor1, System.Double factor2) {
            object[] results = this.Invoke("multiplier", new object[] {
                        factor1,
                        factor2});
            return ((System.Double)(results[0]));
        }

        /// 
        public System.IAsyncResult Beginmultiplier(System.Double factor1, System.Double factor2, System.AsyncCallback callback, object asyncState) {
            return this.BeginInvoke("multiplier", new object[] {
                        factor1,
                        factor2}, callback, asyncState);
        }

        /// 
        public System.Double Endmultiplier(System.IAsyncResult asyncResult) {
            object[] results = this.EndInvoke(asyncResult);
            return ((System.Double)(results[0]));
        }

        /// 
        [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="http://trunk.v.pfapi.remote_api", ResponseNamespace="http://trunk.v.pfapi.remote_api")]
        [return: System.Xml.Serialization.SoapElementAttribute("get_structReturn")]
        public Map get_struct() {
            object[] results = this.Invoke("get_struct", new object[0]);
            return ((Map)(results[0]));
        }

        /// 
        public System.IAsyncResult Beginget_struct(System.AsyncCallback callback, object asyncState) {
            return this.BeginInvoke("get_struct", new object[0], callback, asyncState);
        }

        /// 
        public Map Endget_struct(System.IAsyncResult asyncResult) {
            object[] results = this.EndInvoke(asyncResult);
            return ((Map)(results[0]));
        }

        /// 
        [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="http://trunk.v.pfapi.remote_api", ResponseNamespace="http://trunk.v.pfapi.remote_api")]
        [return: System.Xml.Serialization.SoapElementAttribute("struct_keycountReturn")]
        public System.Double struct_keycount(Map theStruct) {
            object[] results = this.Invoke("struct_keycount", new object[] {
                        theStruct});
            return ((System.Double)(results[0]));
        }

        /// 
        public System.IAsyncResult Beginstruct_keycount(Map theStruct, System.AsyncCallback callback, object asyncState) {
            return this.BeginInvoke("struct_keycount", new object[] {
                        theStruct}, callback, asyncState);
        }

        /// 
        public System.Double Endstruct_keycount(System.IAsyncResult asyncResult) {
            object[] results = this.EndInvoke(asyncResult);
            return ((System.Double)(results[0]));
        }
    }

    /// 
    [System.Xml.Serialization.SoapTypeAttribute("Map", "http://xml.apache.org/xml-soap")]
    public class Map {

        /// 
        public mapItem[] item;
    }

    /// 
    [System.Xml.Serialization.SoapTypeAttribute("mapItem", "http://xml.apache.org/xml-soap")]
    public class mapItem {

        /// 
        public object key;

        /// 
        public object value;
    }

    /// 
    [System.Xml.Serialization.SoapTypeAttribute("QueryBean", "http://rpc.xml.coldfusion")]
    public class QueryBean {

        /// 
        public string[] columnList;

        /// 
        public object[] data;
    }

    /// 
    [System.Xml.Serialization.SoapTypeAttribute("CFCInvocationException", "http://rpc.xml.coldfusion")]
    public class CFCInvocationException {
    }
}

И наконец, мое приложение CLI, которое тестирует сервис:

using System;

namespace pfapi_test
{
 /// 
 /// Summary description for Class1.
 /// 
 class Class1
 {
  /// 
  /// The main entry point for the application.
  /// 
  [STAThread]
  static void Main(string[] args)
  {
   //
   // TODO: Add code to start application here
   //

   Console.WriteLine("Instantiating WS");

   remote_io_test.remote_io_testService testWS = new remote_io_test.remote_io_testService();

   Console.WriteLine("Calling multiplier(3,15)");
   Console.WriteLine(testWS.multiplier(3,15));

   Console.WriteLine("Calling get_struct()");
   remote_io_test.Map theStruct = testWS.get_struct();
   Console.Write("result: ");
   Console.WriteLine(theStruct);
   Console.Write("result.item: ");
   Console.WriteLine(theStruct.item);

   Console.WriteLine("Press Enter to exit...");
   Console.ReadLine();
  }
 }
}

Независимо от того, что я пробую, theStruct.item всегда является "неопределенным значением" согласно отладчику. Печатный вывод похож:

Instantiating WS
Calling multiplier(3,15)
45
Calling get_struct()
result: pfapi_test.remote_io_test.Map
result.item:
Press Enter to exit...

Я попытался использовать ColdFusion 8, и нет никакого различия. Я попытался возвратить реальную пользовательскую базу данных с двумя свойствами вместо моего специального ассоциативного массива, и это хорошо работает, но перезапись моего API для предотвращения ассоциативных массивов не является действительно опцией в это время. API хорошо работает с ColdFusion, PHP/NuSOAP и Ruby on Rails, таким образом, кажется, что должно быть возможно получить его работающий с.NET также.

Я надеюсь, что кто-то может обеспечить некоторое понимание. У меня есть подозрение, что существует некоторая проблема пространства имен здесь, но я не знаю, что SOAP и XML достаточно хорошо выясняют, каково это. Я также искал как безумный решение онлайн, но я не нашел единственного человека, который решил эту проблему, которая очень приводит в уныние!

Запрос:

POST /remote_api/pfapi/v/trunk/remote_io_test.cfc HTTP/1.1
VsDebuggerCausalityData: [snip]
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 1.1.4322.2443)
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 488
Expect: 100-continue
Host: leon.cupahr.tafkan.nooch



  
    
  

Ответ:

HTTP/1.1 200 OK
Date: Thu, 17 Dec 2009 15:14:33 GMT
Server: Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.7l DAV/2 PHP/5.2.8 JRun/4.0 Phusion_Passenger/2.2.7
Set-Cookie: CFID=21543;expires=Sat, 10-Dec-2039 15:14:33 GMT;path=/
Set-Cookie: CFTOKEN=479cc311ca4875db-9D346355-ED36-6183-C8895635E4EE1252;expires=Sat, 10-Dec-2039 15:14:33 GMT;path=/
Transfer-Encoding: chunked
Content-Type: text/xml; charset=utf-8



 
  
   
    
     FOO
     bar
    
    
     ANOTHERKEY
     another value
    
   
  
 

Обновление: Я получил известие от разработчика.NET на другом конце, и он попробовал все следующие напрасно:

  • использование WCF вместо ASMX
  • использование.NET 3.5
  • использование VB.NET для общения с веб-сервисом вместо C#

Он действительно отправлял мне снимок экрана раздела "Data Type" Сервисного Ссылочного диалогового окна Настроек. Действительно ли возможно, что изменение настроек для типа Набора и типа набора Словаря могло бы решить этот вопрос?

Обновление 2: вот код ColdFusion для remote_io_test.cfc




    
    
    
    
 



    
    

    
 



    

    
 

Спасибо за чтение и заранее спасибо за Ваши ответы!

Перекрестно разосланный в тексте ссылки

6
задан Dan McGrath 9 February 2010 в 06:38
поделиться

2 ответа

Я не очень понимаю вопрос. В State Design образца совершенно ясно. См. книгу узоров проектирования .

class SuperState( object ):
    def someStatefulMethod( self ):
        raise NotImplementedError()
    def transitionRule( self, input ):
        raise NotImplementedError()

class SomeState( SuperState ):
    def someStatefulMethod( self ):
        actually do something()
    def transitionRule( self, input ):
        return NextState()

Это довольно распространенный образец, используемый в Java, C++, Python (и я уверен, что другие языки, также).

Если ваши правила перехода состояния оказываются тривиальными, есть некоторые оптимизации, чтобы переместить само правило перехода в суперкласс.

Обратите внимание, что мы должны иметь прямые ссылки, поэтому мы ссылаемся на классы по имени и используем eval для перевода имени класса в фактический класс. Альтернативой является создание переменных экземпляра правил перехода вместо переменных класса, а затем создание экземпляров после определения всех классов.

class State( object ):
    def transitionRule( self, input ):
        return eval(self.map[input])()

class S1( State ): 
    map = { "input": "S2", "other": "S3" }
    pass # Overrides to state-specific methods

class S2( State ):
    map = { "foo": "S1", "bar": "S2" }

class S3( State ):
    map = { "quux": "S1" }

В некоторых случаях ваше событие не так просто, как проверка объектов на равенство, поэтому более общим правилом перехода является использование правильного списка пар «функция-объект».

class State( object ):
    def transitionRule( self, input ):
        next_states = [ s for f,s in self.map if f(input)  ]
        assert len(next_states) >= 1, "faulty transition rule"
        return eval(next_states[0])()

class S1( State ):
    map = [ (lambda x: x == "input", "S2"), (lambda x: x == "other", "S3" ) ]

class S2( State ):
    map = [ (lambda x: "bar" <= x <= "foo", "S3"), (lambda x: True, "S1") ]

Поскольку правила вычисляются последовательно, это позволяет использовать правило «по умолчанию».

-121--1117091-

Я нашел ответ:

f.object.id
-121--2695363-

Не используйте структуры Coldfusion в вашей веб-службе.

Как и все до нас, мы отказались и переписали наш API, чтобы не использовать ассоциативные массивы в запросе или ответе. Теперь мы используем скаляры, массивы и complexTypes, которые автоматически создаются из CFC. На этот раз мы проверили нашу концепцию с PHP, Ruby, Coldfusion, Java и .NET, чтобы убедиться, что она действительно совместима.

Сейчас имеет большой смысл, что статически типизированный язык не сможет обрабатывать полностью произвольный удаленный тип данных в любом разумном пути.

Спасибо за все ваши отзывы!

1
ответ дан 17 December 2019 в 18:16
поделиться

Я сам боролся с этим пунктом со стороны .NET клиента - я пытаюсь использовать веб-сервис, написанный на ColdFusion. Из документации, которую я нашел, тип данных структуры в ColdFusion не отображается непосредственно на какие-либо типы веб-сервисов, и мне кажется, что это вина Axis.

Вы, вероятно, читали те же самые веб-страницы, что и я, когда пытался решить эту проблему, но если вы хотите создать веб-сервис с помощью ColdFusion, рекомендую не использовать тип структуры. Если ваш веб-сервис еще не жив, и вы можете уйти от использования чего-то другого, я бы посоветовал пойти по этому пути. Я попробовал вернуть объекты из ColdFusion, которые отлично работали для меня от клиента .NET.

На самом деле я отказался от этой проблемы и написал пользовательский клиент для моей .NET программы, который просто прочитал бы Xml, возвращенный веб-сервисом ColdFusion, и преобразовал бы его в словарь, так как я не имею никакого влияния на сервис, который я пытаюсь вызвать.

Одна вещь, которую я нашел во время моего тестирования - сервис, который я пытаюсь вызвать, работает на более старой версии ColdFusion (7, на мой взгляд). Всякий раз, когда я звоню в этот сервис, .NET клиент возвращает ноль. Я установил ColdFusion на свою машину и написал простой сервис, и обнаружил, что .NET клиент вернул объект типа Map (который пришел из WSDL), но все свойства объекта Map были нулевыми.

Мне было бы интересно посмотреть, решит ли проблему предложение Криса Хааса в комментариях к вашему вопросу об установке dotNetSoapEncFix.

.
2
ответ дан 17 December 2019 в 18:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: