I'm setting up a really simple WCF service whos only job is to receive an XML-message via SOAP and send the message on to an internal service. Let's say the one I'm creating is a guardpost of such. (Actual names have been substituted for example)
Initial info:
I cannot change the external service calling on me. As far as I know it's a Soap11 client built in java.
All names has been changed to dummy-names in this example.
Endpoint-setup:
<service behaviorConfiguration="GuardpostBehavior" name="Guardpost.ContractImplementation">
<endpoint address="" binding="basicHttpBinding" contract="Guardpost.IContract" bindingConfiguration="basic">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
Binding configuration:
<basicHttpBinding>
<binding name="basic" textEncoding="utf-8" messageEncoding="Text">
<security mode="Transport" />
</binding>
</basicHttpBinding>
(I need Transport-security due to https)
My Contract looks like this:
[ServiceContract]
public interface IContract
{
[OperationContract(Action="urn:#GuardpostReceive")]
void GuardpostReceive(string inputXml);
}
Now what I receive is a Soap-wrapped message that has its Action set to urn:#Guard开发者_Python百科postReceive, so the actual routing of the message is done correctly.
However - When the message is received it isn't actually pushed into the method because of this error:
OperationFormatter encountered an Invalid Message body. Expected to find node type 'Element' with name 'inputXml' and namespace 'http://tempuri.org/'. Found node type 'Element' with name 'extns:ExternalNodeName' and namespace 'http://foo.com/bar.org/someservice/schema/1'
The problem seems to be that my WCF-service is unable to extract the body of the Soap-message and simply pass it as plain XML, but that is what I need it to do.
Have I encountered a showstopper in WCF?
You can define a contract to receive the entire SOAP message and skip the routing entirely:
[ServiceContract]
public interface IUniversalRequestReply
{
[OperationContract(Action = "*", ReplyAction = "*")]
Message ProcessMessage(Message msg);
}
[ServiceContract]
public interface IUniversalOneWay
{
[OperationContract(Action = "*", IsOneWay=true)]
void ProcessMessage(Message msg);
}
But I think you wouldn't be able to do something like:
[ServiceContract]
public interface IContract
{
[OperationContract(Action="urn:#GuardpostReceive")]
void GuardpostReceive(Message inputXml);
}
What are you trying to accomplish in the actual implementation of the operation?
If you define parameter as String you have to pass encoded XML - like <element/>. If you need to pass unencoded XML try to use XmlElement or XElement as a parameter.
精彩评论