I need to create a SOAP webservice that will be consumed by a partnering company. The partnering company has supplied an example of a WSDL file for the service, as there are some naming conventions for methods and objects that must match theirs. It is a fairly simple webservice, with an execute method that takes an array of NameValue objects as input, and returns a boolean. This WSDL file is clearly for a SOAP webservice written in Java.
I have used svcutil to generate classes using their WSDL, to use for my own webservice, which is written in C# as a WCF service. The service is deployed, and I can call it using SOAPUI and get the expected results.
The partnering company however tells me that the WSDL for my webservice doesn't match the expected, and that my service cannot be called from their system. The error they are getting on their end is:
The message with Action 'execute' 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, e.g.
Message, Transport, None).
When inspecting the WSDL produced by my WCF service, I see that some of the names are not the same as in their WSDL file. For example, the request message for the execute operation in their WSDL is called request but in my WSDL it is now called IMyService_execute_InputMessage.
How can I change my WCF service, so that the resulting WSDL matches that of the partnering company's WSDL?
Related
I have added a Service Reference that points to WSDL of the service. I can consume the service by creating a proxy and theres no issue with that. My problem is that I need to send a specific soap message , and theres some parameters that need to be include into the header and the body of the soap message (credentials and IDs).
How I can manually edit or add this soap message? without touching the app.config file?, there's a way to add the same parameters inside the code? such as:
soap:Header
soap:Body
I have a WCF SOAP service that responds with licensing information. The client will save the SOAP response and load it every time the program loads, verifying the user is not passed the expiration date etc. Because of this, one of the requirements of the response is to have a signature such that the client can run the data through some encryption algorithm and check the result against the signature that was sent over to verify nothing has been changed about the file. This is nothing new, this is XML signing. However, the service is written with DataContractSerializer, so I can't just take the data, create an XML signature, and inject that straight into the SOAP response.
I know WsHttpBinding has some security features, the WS-Security page on MSDN describes the Ws binding protocol WRT to SOAP as having the ability to...
Identify the entity or entities involved with the message.
Prove that the entities have the correct group memberships.
Prove that the entities have the correct set of access rights.
Prove that the message has not changed.
but I can't find exactly how it does that last part. Looking at the SOAP response I get with WsHttpBinding on, I see CipherData and CipherValue, but researching that leads me to believe that's more to do with the actual message encryption, not content validation. I see something like ValidateResponse and ValidateResult, but those look like spaces for another endpoint to validate the information, and this product needs to work on devices not connected to the internet once the file is gotten from this service.
I know I could theoretically just put all the data into a variable and SHA256 it and tell my client to do the same process but that's dirty and very unstandardized. I feel like there should be an equivalent to XML Signatures for SOAP responses but I can't find anything through searching.
wsHttpBinding supports WS-Security, which includes digital signature in the SOAP message. To enable it, you need to use the ServiceContractAttribute.ProtectionLevel or the OperationContractAttribute.ProtectionLevel on the service contract definition, rather than doing it in the service configuration like you would expect
So, on your service contract:
[ServiceContract(ProtectionLevel=ProtectionLevel.EncryptAndSign)]
public interface IMyServiceThatIWantToEncyptAndSign
{
...
}
or
[ServiceContract(ProtectionLevel=ProtectionLevel.Sign)]
public interface IMyServiceThatIWantToSign
{
...
}
or
[OperationContract(ProtectionLevel=ProtectionLevel.EncryptAndSign)]
string MyOperationThatIWantToEncryptAndSignSign(string msg);
or
[OperationContract(ProtectionLevel=ProtectionLevel.Sign)]
string MyOperationThatIWantToSign(string msg);
The default value for this is ProtectionLevel.None which is why I think you are not seeing any signature.
The relevant MSDN links are here for the service contract:
http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx
and here for the operation contract:
http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.aspx
I am trying to make an asynchronous call to a web service using BeginXXX and EndXXX methods from C# client. I am using a proxy class generated by using SvcUtil.exe.
The soap message that I expect to send should contain soap header elements for ws-addressing which include tags:
'wsa:Action'
'wsa:MessageID'
'wsa:ReplyTo'
'wsa:To'
However the soap header section is currently empty and only soap body contains body information.
Without the wsa tags, it looks like a synchronous call.
Is there a way to use proxy generated in C#, to invoke a service asynchronously such that the soap message contains wsa tags?
Appreciate any input with regards to this
I need to create a service that will be "called back" by a third party. As a result, I need to conform to their WSDL.
Their WSDL has all of the operations defined with soapAction="", so my service needs to do the same. Unfortunately, I'm getting the error:
The operations A and
B have
the same action (). Every operation
must have a unique action value.
In ASMX web services, there was a mode where the soapAction would not be used, but the name of the request element would be used instead. Is there some way using WCF not only to dispatch on the request element, but also to emit a WSDL with no soapAction?
This is possible in asmx, but out of the box you will find no clean way to do this in WCF because it uses the action to dispatch messages to operations.
I think the hack you need is to set your soapAction to "*", and then write a custom dispatcher.
A potential side effect of this is a bad WSDL, if you need to expose a WSDL you will have to generate/steal it and then use the externalMetadataLocation attribute
I've generated a WCF proxy from a WSDL file, but now when I call the proxy methods, they return null. I've enabled message logging, and can see that the messages from the server are correctly returned.
I've checked the answer of this question, but in my case at least the name of the returned object was the same in the message and in the WSDL. I still believe the problem has to do with the WSDL file, since it is not fetched the usual way through the "?wsdl" URL (it is a 3rd party webservice), but was given separately.
The return type of the method is just a string.
Has anyone else had similar problems, and what was the corresponding solution, if any? What is the most likely source of the problem?
Re-edit:
It is a RPC/Encoded web service. As written, I can see the SOAP response through message logging, but WCF seems not to be able to parse the information.
The message part of the response from the service looks like this:
<ns1:ServiceResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="the target namespace">
<ns1:ReturnValue xsi:type="xsd:string">
However, when inspecting the outgoing message from my client, it's different:
<ns1:ServiceRequest soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="the target namespace">
<RequestValue xsi:type="xsd:string" xmlns="">
So maybe the proxy expects the response to have the same namespace structure, and thus fails to parse it.
I've tried to change the type attribute to element in the wsdl message definitions, and adding some new elements in the types part of the wsdl definition, but then the svcutil chokes when generating the proxy, complaining that there's a clash between the inferred style document and specified style rpc.
From the WSDL specification, section 3.5:
If use is encoded, then each message part references an abstract type using the type attribute.
But then I'm a bit confused, since it doesn't seem to have been a problem in this question. What would be needed to make a similar change, with the restriction that it is a RPC/encoded service?
You'll have to give specifics about the Java service in order to resolve this. However, I suspect that the Java service is using message parts defined with the type attribute. These do not conform to WS-I Basic Profile 1 because there is ambiguity about which namespace should be used for the elements of the message. Some services will use the namespace of the type, while others will (correctly) use the namespace of the web service itself.
Using the element attribute removes the ambiguity, and is therefore preferred.
Please post a snippet of the WSDL containing one of the messages you're having trouble with. When you then compare the definition of the message with what you're seeing on the wire, and then compare that to the details of the proxy class that's meant to consume the message, I believe you'll see what I mean. The proxy class is expecting one namespace, but on the wire, a different namespace is being used.
We have had something similar when using a WCF client against a WSDL from a Java web service.
Our problem was that we could not see the data that was coming back from the service, it looked like the data was missing.
However, when we looked at what was going over the wire, the data was there.
The problem was that the WSDL had many types that inherited from other types. By default we would only see the information in the base type.
The solution was to cast the object to the type we expected, then all the fields appeared.