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

Re: DotNet Client to SOAP::Lite Server with Complex Data Returned

Expand Messages
  • lacombeperl
    ... to ... Since I didn t get any responses, I assume this is too trivial for most in the group, but if there are users having trouble getting dotNet to talk
    Message 1 of 2 , Jul 12, 2004
    • 0 Attachment
      --- In soaplite@yahoogroups.com, "lacombeperl" <lacombeperl@y...>
      wrote:
      > Greetings,
      >
      > I was wondering if any one would be kind enough to post a complete
      > example of a DotNet Client using a WSDL to access a Perl SOAP::Lite
      > server that returns a complex data type.
      >
      > It would be nice to have:
      > .Net client code
      > wsdl
      > perl server code
      >
      > I have been able to access simple data types, and have been trying
      to
      > use Alberto's serializer (from message 'RE: [soaplite] SOAP::Lite
      > server, .NET client, complex types') to get a simple structure to
      > work.
      >
      > Thanks very much for any help,
      > Drew.


      Since I didn't get any responses, I assume this is too trivial
      for most in the group, but if there are users having trouble
      getting dotNet to talk to SOAP::Lite server here is a working
      example to get you started and hopefully save you some time.

      Kudos and credit to Alberto for his serializer.


      **************** W S D L *********************************
      <?xml version="1.0" encoding="utf-8"?>
      <definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:s="http://www.w3.org/2001/XMLSchema"
      xmlns:s0="http://xxxxxxxxxx/interop"
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
      xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
      xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
      targetNamespace="http://xxxxxxxxxx/interop"
      xmlns="http://schemas.xmlsoap.org/wsdl/">
      <types>
      <s:schema elementFormDefault="qualified"
      targetNamespace="http://xxxxxxxxxx/interop">
      <s:element name="getInteropRecords">
      <s:complexType>
      <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="aoi"
      type="s:string" />
      </s:sequence>
      </s:complexType>
      </s:element>
      <s:element name="getInteropRecordsResponse">
      <s:complexType>
      <s:sequence>
      <s:element minOccurs="1" maxOccurs="1"
      name="getInteropRecordsResult" type="s0:interopRecord" />
      </s:sequence>
      </s:complexType>
      </s:element>
      <s:complexType name="interopRecord">
      <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="name"
      type="s:string" />
      <s:element minOccurs="0" maxOccurs="1" name="description"
      type="s:string" />
      <s:element minOccurs="0" maxOccurs="1" name="quantity"
      type="s:int" />
      <s:element minOccurs="0" maxOccurs="1" name="price"
      type="s:float" />
      </s:sequence>
      </s:complexType>
      </s:schema>
      </types>
      <message name="getInteropRecordsSoapIn">
      <part name="parameters" element="s0:getInteropRecords" />
      </message>
      <message name="getInteropRecordsSoapOut">
      <part name="parameters" element="s0:getInteropRecordsResponse" />
      </message>
      <portType name="interopSoap">
      <operation name="getInteropRecords">
      <input message="s0:getInteropRecordsSoapIn" />
      <output message="s0:getInteropRecordsSoapOut" />
      </operation>
      </portType>
      <binding name="interopSoap" type="s0:interopSoap">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
      style="document" />
      <operation name="getInteropRecords">
      <soap:operation
      soapAction="http://xxxxxxxxxx/interop#getInteropRecords"
      style="document" />
      <input>
      <soap:body use="literal" />
      </input>
      <output>
      <soap:body use="literal" />
      </output>
      </operation>
      </binding>
      <service name="interop">
      <port name="interopSoap" binding="s0:interopSoap">
      <soap:address location="http://xxxxxxxxxx/cgi-
      bin/interop/interop_server.pl" />
      </port>
      </service>
      </definitions>



      ************ S E R V E R **************************

      #!/usr/bin/perl -w
      use SOAP::Transport::HTTP;
      use SOAP::Lite +trace;

      use lib "/var/www/cgi-bin/interop";

      use LiteralSerializer;

      $uri = 'http://xxxxxxxxxx/interop';

      SOAP::Transport::HTTP::CGI
      -> dispatch_to('interop')
      -> serializer(LiteralSerializer->new)
      -> handle;

      exit;



      ***************** F U N C T I O N ********************


      package interop;

      require Exporter;
      @ISA = qw(Exporter);
      @EXPORT = qw( getInteropRecords );


      #################################################
      sub getInteropRecords
      {
      my ($class, $aoi) = @_;

      my($nm,$desc,$qty,$price);

      # Don't give the individual data elements uri's
      # One uri is added for the whole record in the
      LiteralSerializer::envelope function

      # Here is an example of what not to do
      #$nm = SOAP::Data->name('name')
      # ->type('string')
      # ->uri($main::uri)
      # ->value('Sudsy Soap');


      $nm = SOAP::Data->name('name')
      ->type('string')
      ->value('Sudsy Soap');

      $desc = SOAP::Data->name('description')
      ->type('string')
      ->value('Bar of Sudsy Soap soap');

      $qty = SOAP::Data->name('quantity')
      ->type('int')
      ->value(3);

      $price = SOAP::Data->name('price')
      ->type('float')
      ->value(1.55);


      # Don't give the record a uri, either
      # This will not work
      #return SOAP::Data->name('getInteropRecordsResult' =>
      # \SOAP::Data->value(
      # $nm,
      # $desc,
      # $qty,
      # $price
      # )
      # )
      # ->type('interopRecord')
      # ->uri($main::uri);

      return SOAP::Data->name('getInteropRecordsResult' =>
      \SOAP::Data->value(
      $nm,
      $desc,
      $qty,
      $price
      )
      )
      ->type('interopRecord');
      }


      1;




      ************** L I T E R A L S E R I A L I Z E R **************

      package LiteralSerializer;

      require Exporter;
      @ISA = qw(Exporter);
      @EXPORT = qw( xmlize envelope );

      @LiteralSerializer::ISA = 'SOAP::Serializer';


      #################################################
      sub xmlize
      {
      my $self = shift;
      my($name, $attrs, $values, $id) = @{+shift};
      my($a,$attr,$val, $val2);
      $attrs ||= {};

      # keep only namespace attributes for all elements
      $a = $attrs->{xmlns} ? {xmlns => $attrs->{xmlns}} : {};

      return $self->SUPER::xmlize([$name, $a, $values, $id]);
      }

      #################################################
      sub envelope
      {
      my(@params) = @_;

      $_[2] = (UNIVERSAL::isa($_[2] => 'SOAP::Data') ? $_[2] :
      SOAP::Data->name($_[2])->attr({xmlns => $main::uri}))
      if $_[1] =~ /^(?:method|response)$/;

      shift->SUPER::envelope(@_);

      }


      1;



      ***************** D O T N E T C L I E N T **************

      // ADD A WEB REFERENCE POINTING TO ABOVE WSDL ON SERVER
      // IN THIS CASE I CALLED IT 'interopService'


      ...

      interopService.interop iss = new interopService.interop();
      interopService.interopRecord irec;

      irec = iss.getInteropRecords("testing");

      String name = irec.name;
      String description = irec.description;
      int quantity = irec.quantity;
      float price = irec.price;

      txt_output.Text = "Name: " + name +
      ", Description: " + description +
      ", Quantity: " + quantity.ToString() +
      ", Price: " + price.ToString();


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