How to use SOAP :: Lite with WCF?

I'm just trying to get started with WCF. It seems like it's super simple, but using a simple API like SOAP :: Lite, I'm having trouble working. There are many dated examples in googlesphere, and I tried many of them to no avail. So now I am trying to break the problem to the lowest level. I created a WCF application created by the Visual Web Developer 2008 Express template. This is his service contract:

[ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); // TODO: Add your service operations here } // Use a data contract as illustrated in the sample below to add composite types to service operations. [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } } 

I started it in debug mode and tried to establish contact. Doing this using a browser using the debug url http://localhost:59315/Service1.svc gives me a page that says the following:

You have created a service.

To test this service, you need to create a client and use it to call the service. You can do this using the svcutil.exe tool from the command line with the following syntax:

svcutil.exe http://localhost:59315/Service1.svc?wsdl

So then I go to this wsdl and get the following:

 <wsdl:definitions name="Service1" targetNamespace="http://tempuri.org/"> <wsp:Policy wsu:Id="WSHttpBinding_IService1_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SymmetricBinding> <wsp:Policy> <sp:ProtectionToken> <wsp:Policy> <sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:RequireDerivedKeys/> <sp:BootstrapPolicy> <wsp:Policy> <sp:SignedParts> <sp:Body/> <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> </sp:SignedParts> <sp:EncryptedParts> <sp:Body/> </sp:EncryptedParts> <sp:SymmetricBinding> <wsp:Policy> <sp:ProtectionToken> <wsp:Policy> <sp:SpnegoContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:RequireDerivedKeys/> </wsp:Policy> </sp:SpnegoContextToken> </wsp:Policy> </sp:ProtectionToken> <sp:AlgorithmSuite> <wsp:Policy> <sp:Basic256/> </wsp:Policy> </sp:AlgorithmSuite> <sp:Layout> <wsp:Policy> <sp:Strict/> </wsp:Policy> </sp:Layout> <sp:IncludeTimestamp/> <sp:EncryptSignature/> <sp:OnlySignEntireHeadersAndBody/> </wsp:Policy> </sp:SymmetricBinding> <sp:Wss11> <wsp:Policy> <sp:MustSupportRefKeyIdentifier/> <sp:MustSupportRefIssuerSerial/> <sp:MustSupportRefThumbprint/> <sp:MustSupportRefEncryptedKey/> </wsp:Policy> </sp:Wss11> <sp:Trust10> <wsp:Policy> <sp:MustSupportIssuedTokens/> <sp:RequireClientEntropy/> <sp:RequireServerEntropy/> </wsp:Policy> </sp:Trust10> </wsp:Policy> </sp:BootstrapPolicy> </wsp:Policy> </sp:SecureConversationToken> </wsp:Policy> </sp:ProtectionToken> <sp:AlgorithmSuite> <wsp:Policy> <sp:Basic256/> </wsp:Policy> </sp:AlgorithmSuite> <sp:Layout> <wsp:Policy> <sp:Strict/> </wsp:Policy> </sp:Layout> <sp:IncludeTimestamp/> <sp:EncryptSignature/> <sp:OnlySignEntireHeadersAndBody/> </wsp:Policy> </sp:SymmetricBinding> <sp:Wss11> <wsp:Policy> <sp:MustSupportRefKeyIdentifier/> <sp:MustSupportRefIssuerSerial/> <sp:MustSupportRefThumbprint/> <sp:MustSupportRefEncryptedKey/> </wsp:Policy> </sp:Wss11> <sp:Trust10> <wsp:Policy> <sp:MustSupportIssuedTokens/> <sp:RequireClientEntropy/> <sp:RequireServerEntropy/> </wsp:Policy> </sp:Trust10> <wsaw:UsingAddressing/> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="WSHttpBinding_IService1_GetData_Input_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedParts> <sp:Body/> <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> </sp:SignedParts> <sp:EncryptedParts> <sp:Body/> </sp:EncryptedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="WSHttpBinding_IService1_GetData_output_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedParts> <sp:Body/> <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> </sp:SignedParts> <sp:EncryptedParts> <sp:Body/> </sp:EncryptedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="WSHttpBinding_IService1_GetDataUsingDataContract_Input_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedParts> <sp:Body/> <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> </sp:SignedParts> <sp:EncryptedParts> <sp:Body/> </sp:EncryptedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="WSHttpBinding_IService1_GetDataUsingDataContract_output_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedParts> <sp:Body/> <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> </sp:SignedParts> <sp:EncryptedParts> <sp:Body/> </sp:EncryptedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsdl:types> <xsd:schema targetNamespace="http://tempuri.org/Imports"> <xsd:import schemaLocation="http://localhost:59315/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/"/> <xsd:import schemaLocation="http://localhost:59315/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/> <xsd:import schemaLocation="http://localhost:59315/Service1.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/RossDominosService"/> </xsd:schema> </wsdl:types> <wsdl:message name="IService1_GetData_InputMessage"> <wsdl:part name="parameters" element="tns:GetData"/> </wsdl:message> <wsdl:message name="IService1_GetData_OutputMessage"> <wsdl:part name="parameters" element="tns:GetDataResponse"/> </wsdl:message> <wsdl:message name="IService1_GetDataUsingDataContract_InputMessage"> <wsdl:part name="parameters" element="tns:GetDataUsingDataContract"/> </wsdl:message> <wsdl:message name="IService1_GetDataUsingDataContract_OutputMessage"> <wsdl:part name="parameters" element="tns:GetDataUsingDataContractResponse"/> </wsdl:message> <wsdl:portType name="IService1"> <wsdl:operation name="GetData"> <wsdl:input wsaw:Action="http://tempuri.org/IService1/GetData" message="tns:IService1_GetData_InputMessage"/> <wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataResponse" message="tns:IService1_GetData_OutputMessage"/> </wsdl:operation> <wsdl:operation name="GetDataUsingDataContract"> <wsdl:input wsaw:Action="http://tempuri.org/IService1/GetDataUsingDataContract" message="tns:IService1_GetDataUsingDataContract_InputMessage"/> <wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataUsingDataContractResponse" message="tns:IService1_GetDataUsingDataContract_OutputMessage"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="WSHttpBinding_IService1" type="tns:IService1"> <wsp:PolicyReference URI="#WSHttpBinding_IService1_policy"/> <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="GetData"> <soap12:operation soapAction="http://tempuri.org/IService1/GetData" style="document"/> <wsdl:input> <wsp:PolicyReference URI="#WSHttpBinding_IService1_GetData_Input_policy"/> <soap12:body use="literal"/> </wsdl:input> <wsdl:output> <wsp:PolicyReference URI="#WSHttpBinding_IService1_GetData_output_policy"/> <soap12:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetDataUsingDataContract"> <soap12:operation soapAction="http://tempuri.org/IService1/GetDataUsingDataContract" style="document"/> <wsdl:input> <wsp:PolicyReference URI="#WSHttpBinding_IService1_GetDataUsingDataContract_Input_policy"/> <soap12:body use="literal"/> </wsdl:input> <wsdl:output> <wsp:PolicyReference URI="#WSHttpBinding_IService1_GetDataUsingDataContract_output_policy"/> <soap12:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Service1"> <wsdl:port name="WSHttpBinding_IService1" binding="tns:WSHttpBinding_IService1"> <soap12:address location="http://localhost:59315/Service1.svc"/> <wsa10:EndpointReference> <wsa10:Address>http://localhost:59315/Service1.svc</wsa10:Address> <Identity> <Dns>localhost</Dns> </Identity> </wsa10:EndpointReference> </wsdl:port> </wsdl:service> </wsdl:definitions> 

Nothing too crazy (except for SOAP itself) ... Anyway, now I will try a simple SOAP :: Lite application:

 #!/cygdrive/C/Perl64/bin/perl.exe -w use strict; use warnings; use Data::Dumper; use SOAP::Lite +trace => [ transport => sub { my ($in) = @_; if ( ref($in) eq "HTTP::Request") { print( "REQUEST\n" . $in->content() . "\nEND REQUEST\n" ); } elsif ( ref($in) eq "HTTP::Response") { print( "RESPONSE\n" . $in->content() . "\nEND RESPONSE\n" ); } } ]; my $server = 'http://localhost:59315/Service1.svc'; my $url = "$server?wsdl"; my $xmlns = 'http://schemas.datacontract.org/2004/07/RossDominosService'; # Setup Network Connection my $service = SOAP::Lite ->ns( $url ) ->proxy( $server ) ->on_fault( sub { my ($soap, $res) = @_; die ref $res ? $res->faultstring() : $soap->transport()->status(), "\n"; } ); ; print( Dumper( $service ) ); eval { print( "making request\n" ); my $response = $service->GetData( SOAP::Data->new( name => 'value', value => 5 ) ); print( "got response:\n$response\n" ); }; if ( $@ ) { print( "failed:\n**************************\ n$@ \n*****************************\n" ); } 

Which of the debugging issues this SOAP request:

 <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:namesp1="http://localhost:59315/Service1.svc?wsdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <namesp1:GetData> <value xsi:type="xsd:int">5</value> </namesp1:GetData> </soap:Body> </soap:Envelope> 

But the answer is returned with:

 failed: ************************** 415 Unsupported Media Type ***************************** 

What's happening? This is "Hello world!" SOAP applications, and I can't figure it out.

----------------------- UPDATE -------------------- ------ -----

I found that I need to change the default wsHttpBinding to:

  <endpoint address="" binding="basicHttpBinding" contract="RossDominosService.IService1"> 

Now it connects, but I get this new error:

 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <s:Fault> <faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</faultcode> <faultstring xml:lang="en-US">The message with Action 'http://tempuri.org/GetData' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, eg Message, Transport, None).</faultstring> </s:Fault> </s:Body> </s:Envelope> 

It doesn't seem like it was that hard ...

----------------------- UPDATE -------------------- ------ -----

Got! After some additional intervention and some help from soapUI, I found out that the action needs to be changed so that it:

 <namespace>/<serviceContract>/<method> 

in this case:

 http://tempuri.org/IService1/GetData 

When using SOAP :: Lite SOAPAction by default

 <namespace>#<method> 

So you should change your soap object like this:

 $soap->on_action( sub { sprintf( '%sIService1/%s', @_ ) } ); 

I will write the answer below so that we can close this question ...

+4
source share
1 answer

This is how I ended up working with the WCF web service and working with the perl SOAP :: Lite client. Please note that I am using Visual Web Developer Express 2008 and perl 5.14 with SOAP :: Lite 0.715.

  • Open Visual Web Developer
  • File → New Project ...
    • Visual C # -> Web
    • WCF Service Application
    • Name: WcfService1
    • Location:
    • Solution: New Solution
    • Solution Name:
  • Open Web.config
    • change <compilation debug="false"> to <compilation debug="true">
    • change <endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1"> to <endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1">
  • Open Service1.svc.cs
    • press f5 (to start debugging)

Now a browser window opens, open on your service page. Pay attention to the port in the URL, you will need it for the client. Then create this script:

 #!/cygdrive/C/Perl64/bin/perl.exe -w use strict; use warnings; use Data::Dumper; use SOAP::Lite +trace => [ transport => sub { my ($in) = @_; if ( ref($in) eq "HTTP::Request") { print( "**** REQUEST ****\n" . $in->content() . "\n**** END REQUEST ****\n" ); } elsif ( ref($in) eq "HTTP::Response") { print( "**** RESPONSE ****\n" . $in->content() . "\n**** END RESPONSE ****\n" ); } } ]; my $port = 63181; my $server = "http://localhost:$port/Service1.svc"; my $namespace = 'http://tempuri.org/'; # Setup Network Connection my $service = SOAP::Lite ->ns( $namespace, 'my' ) ->proxy( $server ) ->on_action( sub { my $action = sprintf( '%sIService1/%s', @_ ); print( "action: '$action'\n" ); return $action; } ); print( Dumper( $service ) ); eval { print( "making request\n" ); my $response = $service->GetData( SOAP::Data->new( prefix => 'my', name => 'value', value => 5 ) ); print( "got response:\n$response\n" ); }; if ( $@ ) { print( "failed:\n**************************\ n$@ \n*****************************\n" ); } 

You will need to change the port number according to your port number. In addition, I left a bunch of debugging code so you can see what is happening.

I hope this helps someone else.

+2
source

Source: https://habr.com/ru/post/1432153/


All Articles