Loading ...
Sorry, an error occurred while loading the content.

Re: SOAP::Lite/.net interop

Expand Messages
  • Matt Long
    Mike, I can help you, but keep in mind that I never got it to work with complex types. When I return rows of data, I just convert my data to the equivalent of
    Message 1 of 3 , Mar 4, 2005
    View Source
    • 0 Attachment
      Mike,

      I can help you, but keep in mind that I never got it to work with
      complex types. When I return rows of data, I just convert my data to the
      equivalent of a flat file and return that as a string. It's lame, but it
      works.

      Anyhow, the attachment just says hello. You place the files from the
      perl folder in your web tree where SOAP::Lite is running, then you need
      to update the bottom of the WSDL file I included to reflect the web
      location on your local machine of the actual sayhellodispatcher.cgi file
      (e.g. http://localhost/soap/sayhellodispatcher.cgi). Then you need to
      specify to visual studio your local web address to the WSDL file (e.g.
      http://localhost/soap/HelloSOAPLite.wsdl ) when you add a web reference.

      Let me know if you have any questions.

      -Matt

      p.s. I tested this example and it works.



      m_j_conroy wrote:

      >Matt,
      >
      >I saw your post on Google groups with the WSDL snippet. Do you have
      >an end-to-end example from the .Net code forward for a SOAP::Lite
      >server called by a .Net client? A simple HelloWorld example is
      >literally sufficient. Any help would be much obliged... I realize
      >this email is coming out of the blue.
      >
      >Best,
      >Mike Conroy
      >
      >
      >
      >
      >
      >
      >
    • Jonathan D. Fields
      Hi All, After considerable experimentation, I was able to develop a SOAP Lite server that works with VB/.NET, Java/AXIS, and SOAP Lite clients, using WSDL and
      Message 2 of 3 , Mar 4, 2005
      View Source
      • 0 Attachment
        Hi All,

        After considerable experimentation, I was able to develop a SOAP Lite server that works with VB/.NET, Java/AXIS, and SOAP Lite clients, using WSDL and fairly complex types.

        Below is an example. I haven't actually tried compiling this, as I just threw it together, but it should be pretty close to working as it's based on working code. Time permitting I'll put together a more complete and working example server and clients and post that.

        The bottom line is that it's surprisingly difficult to do this, which to me is a drawback to SOAP Lite if you need to develop web services in SOAP Lite that can be accessed by any SOAP client.  If anyone can provide an easier approach I'd appreciate it. I came very close to encoding the XML myself.

        Thanks,
        Jon


        WSDL:




        <?xml version="1.0" encoding="utf-8"?>

        <definitions name="Ex"
                     targetNamespace="urn:Ex/WebSvc"
                     xmlns:ex="urn:Ex/WebSvc"
                     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                     xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
                     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                     xmlns="http://schemas.xmlsoap.org/wsdl/">

          <types>
            <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
                        targetNamespace="urn:Ex/WebSvc">

            <xsd:complexType name="IntArray">
              <xsd:complexContent>
                <xsd:restriction base="soapenc:Array">
                   <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:int[]"/>
                </xsd:restriction>
              </xsd:complexContent>
            </xsd:complexType>

            <xsd:complexType name="Struct">
              <xsd:all>
                <xsd:element name="elem1"      type="xsd:int"/>
                <xsd:element name="elem2"      type="xsd:string"/>
              </xsd:all>
            </xsd:complexType>

            <xsd:complexType name="StructArray">
              <xsd:complexContent>
                <xsd:restriction base="soapenc:Array">
                   <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="ex:Struct[]"/>
                </xsd:restriction>
              </xsd:complexContent>
            </xsd:complexType>

            <xsd:complexType name="ResultStruct">
              <xsd:all>
                <xsd:element name="elem1"   type="ex:StructArray"/>
                <xsd:element name="elem2"   type="xsd:string"/>
              </xsd:all>
            </xsd:complexType>

            </xsd:schema>
          </types>

          <message name="ExRequest">
            <part name="param1" type="xsd:string" />
            <part name="param2" type="ex:IntArray" />
          </message>
          <message name="ExResponse">
            <part name="return"    type="ex:ResultStruct" />
          </message>

          <portType name="API">

            <operation name="exOp">
              <input message="ex:ExRequest" />
              <output message="ex:ExResponse" />
            </operation>

          </portType>

          <binding name="SOAPBinding" type="ex:API">
            <soap:binding style="rpc"
                          transport="http://schemas.xmlsoap.org/soap/http"/>

            <operation name="exOp">
              <soap:operation soapAction="urn:Ex/WebSvc#exOp"/>
              <input>
                <soap:body use="encoded"
                           namespace="urn:Ex/WebSvc"
                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
              </input>
              <output>

              <output>
                <soap:body use="encoded"
                           namespace="urn:Ex/WebSvc"
                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
              </output>
            </operation>

          </binding>

          <service name="SOAPService">
            <port name="API" binding="ex:SOAPBinding">
              <soap:address location="http://ex.websvc.acme.com:4321/"/>
            </port>
          </service>

        </definitions>



        SOAP Lite Server:



        use SOAP::Lite;

        my $daemon = new SOAP::Transport::HTTP::Daemon(LocalPort => 4321);
        $daemon->dispatch_to('/my/perl/lib', 'Ex::WebSvc');
        $daemon->handle;



        The package implementing the server (in Ex/WebSvc.pm):



        package Ex::WebSvc;

        use SOAP::Lite;
        use vars qw(@ISA);

        @ISA = qw(SOAP::Server::Parameters);

        sub exOp
        {
          shift;
          my ($param1, $param2) = SOAP::Server::Parameters::byNameOrOrder([qw(param1 param2)], @_);

          # $param1 contains a string and $param2 a ref to an array of ints
         
          my @structs = (
            SOAP::Data->name("item")->value(\SOAP::Data->value(SOAP::Data->name("elem1")->value(1),
                                                               SOAP::Data->name("elem2")->value("abcd"))),
            SOAP::Data->name("item")->value(\SOAP::Data->value(SOAP::Data->name("elem1")->value(2),
                                                               SOAP::Data->name("elem2")->value("efgh")))

            #...
          );

          my $structCount = @structs;

          return SOAP::Data->name("return")
                           ->value(\SOAP::Data->value(SOAP::Data->name("elem1")
                                                                ->value(\SOAP::Data->value(@structs))
                                                                ->attr({"xsi:type"           => "SOAP-ENC:Array",
                                                                        "SOAP-ENC:arrayType" => "ex:Struct[$structCount]"}),
                                                      SOAP::Data->name("elem2")
                                                                ->value("uvwxy")))
                           ->attr({"xmlns:ex"  => "urn:Ex/WebSvc",
                                   "xsi:type"  => "ex:ResultStruct"});


        }



        For the VB client, you must first run wsdl.exe to generate the stub code, e.g:

        wsdl /l:VB /n:Ex Ex.wsdl

        Then your client looks something like:



        Class Client
          Public Shared Sub Main()
            Dim ex As New Ex.SOAPService
            Dim intArray(2) As Integer
            intArray(0) = 1
            intArray(1) = 2
            Try
              Dim result As Ex.ResultStruct = ex.exOp("abcd", intArray)
            Catch ..
            End Try
          End Sub
        End Class



        Compile the stub code (SOAPService.vb) together with your client (Client.vb):

        vbc /r:System.dll /r:System.Web.Services.dll /r:System.Xml.dll /out:Client.exe SOAPService.vb Client.vb

        You are ready to go at this point. The Java/AXIS code is similar.

        Ironically, I was not able to get a SOAP Lite client to work with this server using

             my $ex = SOAP::Lite->service('file:Ex.wsdl');

        I forget the exact problem, but I think it had something to do with not handling the IntArray "typedef" in the WSDL. In order to call this server using SOAP Lite, I ended up doing something like: 

        my $ex = SOAP::Lite->proxy('ex.websvc.acme.com:4321')->uri('urn:Ex/WebSvc');
        my $resultStruct = $ex->exOp("abcd", [1, 2, 3, 4])->result;

        print $resultStruct->{elem1}->[0]->{elem1}, "\n";
        print $resultStruct->{elem1}->[0]->{elem2}, "\n";
        print $resultStruct->{elem1}->[1]->{elem1}, "\n";
        print $resultStruct->{elem1}->[1]->{elem2}, "\n";
        print $resultStruct->{elem2}, "\n";




        Matt Long wrote:
        Mike,

        I can help you, but keep in mind that I never got it to work with
        complex types. When I return rows of data, I just convert my data to the
        equivalent of a flat file and return that as a string. It's lame, but it
        works.

        Anyhow, the attachment just says hello. You place the files from the
        perl folder in your web tree where SOAP::Lite is running, then you need
        to update the bottom of the WSDL file I included to reflect the web
        location on your local machine of the actual sayhellodispatcher.cgi file
        (e.g. http://localhost/soap/sayhellodispatcher.cgi). Then you need to
        specify to visual studio your local web address to the WSDL file (e.g.
        http://localhost/soap/HelloSOAPLite.wsdl ) when you add a web reference.

        Let me know if you have any questions.

        -Matt

        p.s. I tested this example and it works.



        m_j_conroy wrote:

        >Matt,
        >
        >I saw your post on Google groups with the WSDL snippet.  Do you have
        >an end-to-end example from the .Net code forward for a SOAP::Lite
        >server called by a .Net client?  A simple HelloWorld example is
        >literally sufficient.  Any help would be much obliged... I realize
        >this email is coming out of the blue.
        >
        >Best,
        >Mike Conroy
        >
        >
        >
        >
        >

        >


      • steve_f_maher
        I got this to work after adding xmlns:SOAP-ENC = http://schemas.xmlsoap.org/soap/encoding/ in the last attr() clause. Great example! Steve
        Message 3 of 3 , May 4, 2005
        View Source
        • 0 Attachment
          I got this to work after adding

          "xmlns:SOAP-ENC" => "http://schemas.xmlsoap.org/soap/encoding/"

          in the last attr() clause.

          Great example!

          Steve
        Your message has been successfully submitted and would be delivered to recipients shortly.