views:

56

answers:

2

Hi!

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:

  1. I cannot change the external service calling on me. As far as I know it's a Soap11 client built in java.

  2. 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:#GuardpostReceive, 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?

A: 

If you define parameter as String you have to pass encoded XML - like &lt;element/&gt;. If you need to pass unencoded XML try to use XmlElement or XElement as a parameter.

Ladislav Mrnka
The problem here isn't the string or input-parameter type, but the OperationFormatter-exception. It happens no matter what I set as the inputtype.
Yngve B. Nilsen
Sorry my fault, I skipped initial paragraph of your question. If you build router you should work with Message type directly (return type of operation has to be also Message). You can't just define string parameter and expect that it will be filled with XML. You can also try to use XmlElement or XElement as parameter type. Alex already showed you an example.
Ladislav Mrnka
+1  A: 

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?

Alex