Reputation: 1442
I'm trying to connect to a SOAP 1.1 webservice, using TLS. The certificate has been set up right, and I am able to communicate with the webservice.
However, when I try to do this using a plain C# project, using proxyclasses generated by VS2010, the request seems to be incomplete, as in, the empty tags are not in the request. I then get a "This is an operation implementation generated fault" fault, viewable in Fiddler
If I then try to launch a request using SoapUI, I get a succesful response from the webservice.
I used Fiddler to compare both requests, and I noticed that the C# request was pretty plain, only sending elements that were filled in in my C# class. But when I check the SoapUI request, this request included EVERY element defined in the WSDL/XSD's, even though they're empty.
I'm trying to understand how I can configure the C# client to include empty elements, to see if the webservice will accept my request, however I was unable to find such setting.
The C# request response:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode xmlns="">
SOAP-ENV:Server
</faultcode>
<faultstring xmlns="">
This is an operation implementation generated fault
</faultstring>
<faultactor xmlns=""/>
<detail xmlns="">
<ns:SOAPFault xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:xxx:xxx:data:soapfault:1:standard" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<ns:ErrorCode>2.0</ns:ErrorCode>
<ns:ErrorText>XML schema validation error</ns:ErrorText>
<ns:ErrorDetails>
/{urn:xxx:xxx:service:contractcancellation:1:standard}ContractCancellationRequestEnvelope[1]/part1[1]/ContractCancellationRequestEnvelope[1]/BusinessDocumentHeader[1]/Destination[1]
</ns:ErrorDetails>
</ns:SOAPFault>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The C# request:
POST xx HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:ContractCancellationRequestEnvelope"
Host: xx
Content-Length: 887
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ContractCancellationRequestEnvelope xmlns="urn:xxx:xxx:data:contractcancellationrequest:1:standard">
<Portaal_Content>
<Portaal_MeteringPoint>
<EANID>xxx</EANID>
<MPCommercialCharacteristics>
<ContractCancellationDate>
2013-11-15
</ContractCancellationDate>
</MPCommercialCharacteristics>
<Portaal_Mutation>
<Initiator>xxx</Initiator>
<Dossier>
<ID>TST0000001</ID>
</Dossier>
</Portaal_Mutation>
</Portaal_MeteringPoint>
</Portaal_Content>
</ContractCancellationRequestEnvelope>
</s:Body>
</s:Envelope>
The SoapUI request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:xxx:xxx:data:contractcancellationrequest:1:standard">
<soapenv:Header/>
<soapenv:Body>
<urn:ContractCancellationRequestEnvelope>
<urn:BusinessDocumentHeader>
<!--Optional:-->
<urn:ContentHash>?</urn:ContentHash>
<!--Optional:-->
<urn:ConversationID>?</urn:ConversationID>
<!--Optional:-->
<urn:CorrelationID>?</urn:CorrelationID>
<urn:CreationTimestamp>?</urn:CreationTimestamp>
<!--Optional:-->
<urn:DocumentID>?</urn:DocumentID>
<!--Optional:-->
<urn:ExpiresAt>?</urn:ExpiresAt>
<urn:MessageID>?</urn:MessageID>
<!--Optional:-->
<urn:ProcessTypeID>?</urn:ProcessTypeID>
<!--Optional:-->
<urn:RepeatedRequest>?</urn:RepeatedRequest>
<!--Optional:-->
<urn:TestRequest>?</urn:TestRequest>
<urn:Destination>
<urn:Receiver>
<!--Optional:-->
<urn:Authority>?</urn:Authority>
<!--Optional:-->
<urn:ContactTypeIdentifier>?</urn:ContactTypeIdentifier>
<urn:ReceiverID>?</urn:ReceiverID>
</urn:Receiver>
<!--Optional:-->
<urn:Service>
<!--Optional:-->
<urn:ServiceMethod>?</urn:ServiceMethod>
<!--Optional:-->
<urn:ServiceName>?</urn:ServiceName>
</urn:Service>
</urn:Destination>
<!--Optional:-->
<urn:Manifest>
<urn:NumberofItems>?</urn:NumberofItems>
<!--1 or more repetitions:-->
<urn:ManifestItem>
<!--Optional:-->
<urn:Description>?</urn:Description>
<!--Optional:-->
<urn:LanguageCode>?</urn:LanguageCode>
<urn:MimeTypeQualifierCode>?</urn:MimeTypeQualifierCode>
<urn:UniformResourceIdentifier>?</urn:UniformResourceIdentifier>
</urn:ManifestItem>
</urn:Manifest>
<urn:Source>
<!--Optional:-->
<urn:Authority>?</urn:Authority>
<!--Optional:-->
<urn:ContactTypeIdentifier>?</urn:ContactTypeIdentifier>
<urn:SenderID>?</urn:SenderID>
</urn:Source>
</urn:BusinessDocumentHeader>
<urn:Portaal_Content>
<urn:Portaal_MeteringPoint>
<urn:EANID>?</urn:EANID>
<urn:MPCommercialCharacteristics>
<urn:ContractCancellationDate>?</urn:ContractCancellationDate>
</urn:MPCommercialCharacteristics>
<urn:Portaal_Mutation>
<!--Optional:-->
<urn:ExternalReference>?</urn:ExternalReference>
<urn:Initiator>?</urn:Initiator>
<!--Optional:-->
<urn:Dossier>
<urn:ID>?</urn:ID>
</urn:Dossier>
</urn:Portaal_Mutation>
</urn:Portaal_MeteringPoint>
</urn:Portaal_Content>
</urn:ContractCancellationRequestEnvelope>
</soapenv:Body>
</soapenv:Envelope>
As you can see, the SoapUI request is far more complete, even though the elements are empty.
C# code (important parts):
_binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
_binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
_endpoint = new EndpointAddress(endpointAddress + "xxx");
_proxy = new ContractCancellationPortTypeClient(_binding, _endpoint);
_proxy.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
"xxx");
_proxy.ContractCancellation(new ContractCancellationRequestEnvelope()
{ Portaal_Content = new ContractCancellationRequestEnvelope_PC()
{ Portaal_MeteringPoint = new ContractCancellationRequestEnvelope_PC_PMP()
{ EANID = request.EanId,
MPCommercialCharacteristics = new ContractCancellationRequestEnvelope_PC_PMP_MPCC()
{ ContractCancellationDate = request.ContractCancellationDate },
Portaal_Mutation = new ContractCancellationRequestEnvelope_PC_PMP_PM()
{ Initiator = request.SupplierEanId,
Dossier = new ContractCancellationRequestEnvelope_PC_PMP_PM_Dossier()
{ ID = "TST0000001" }
}
}
});
Upvotes: 0
Views: 5375
Reputation: 28520
In your code, you're generating the Portaal_Content
portion of the ContractCancellationRequestEnvelope
, but not the BusinessDocumentHeader
portion.
If you look at the fault received (via C#) I'm betting that there's one or more required elements in the BusinessDocumentHeader
section that are missing:
The error text is XML schema validation error
, and the error detail is:
ContractCancellationRequestEnvelope[1]/part1[1]/ContractCancellationRequestEnvelope[1]/BusinessDocumentHeader[1]/Destination[1]
You need to ensure that all required elements are present in your SOAP message.
EDIT
Something like this should do the trick:
ContractCancellationRequestEnvelope reqMsg = new ContractCancellationRequestEnvelope();
reqMsg.BusinessDocumentHeader = new BusinessDocumentHeader()
{ CorrelationTimestamp = "?",
MessageID = "?" };
reqMsg.BusinessDocumentHeader.Destination = new Destination();
reqMsg.BusinessDocumentHeader.Receiver = new Receiver()
{ ReceiverID = "?" };
And so on. Basically, make sure that you create every element that is required.
By the way, you can do nested automatic initialization (as in the code you posted), I simply took a more explicit route in my example for readability.
The service's WSDL will tell you what is required or optional.
If you need more help either provide the URL for the service or post the WSDL.
Upvotes: 1