Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I modify WCF to process messages in a different (non SOAP) format?

I am working with WCF to exchange messages with a third party company. The messages need to be sent and received in an envelope that matches the ebXML specification. Ideally I would like to use as much of the WCF stack as possible and avoid the one method to process them all approach as in this case that would mean writing much of the infrastructure of WCF again.

As far as I can see from my initial research this would require me to write my own custom binding but I am struggling to find clarity in the documentation in MSDN.

I have been able to find lots of detailed documents about in individual implementations of each of these but very little about how to put it all together end to end. It would appear that the books I have are similarly light on these topics too with no mention of this in "Pro WCF" by Peiris and Mulder.

What I am aiming for is something like the following.

The messages being sent and received MUST be formatted like below where the name of the first element is the name of the operation that is to be executed and the child element is the payload of the request message would be of the form:

<?xml version="1.0" encoding="UTF-8"?>
<op:DoSomething xmlns:op="http://my.ebXML.schema.com" xmlns:payload="http://payload.company.com">
    <op:AnObject>
        <payload:ImportantValue>42</payload:ImportantValue>
    </op:AnObject>
</op:DoSomething>

And the response would be:

<?xml version="1.0" encoding="UTF-8"?>
<op:AcknowledgementResponse xmlns:op="http://my.ebXML.schema.com" xmlns:payload="http://payload.company.com">
    <op:ResponseObject>
        <payload:Ok>True</payload:Ok>
    </op:ResponseObject>
</op:AcknowledgementResponse>

As the messages are all described by XML schemas I have used XSD.exe to convert these to strongly typed objects. See https://gist.github.com/740303 for the schemas. Note that these are example schemas. I am not able to post the real schemas without breaching client confidentiality agreements (nor would you want me too as they are huge).

I would now like to be able to write the service implementation as follows:

public class MyEndpoint : IMyEndpoint
{
    public AcknowledgementResponse DoSomething(AnObject value)
    {
        return new AcknowledgementResponse
            {
                Ok = True;
            };
    }
}

Any help would be much appreciated.

like image 890
MikeD Avatar asked Dec 14 '10 09:12

MikeD


1 Answers

I don't think that you need to do anything with bindings. I'm assuming that you need to send the ebXML formatted message over HTTP anyway?

@ladislav's answer is one approach, but I think message encoders are designed to work at a much lower level than what you're trying to achieve. They're essentially the pieces that encode the messages to and from the underlying stream (i.e., how the message is represented as bytes on the stream).

I think what you need to do is implement a custom Message Formatter. In particular, since you say that you want to submit the messages to a third-party, then I think it's only the IClientMessageFormatter interface that you'll need to implement. The other interface (IDispatchMessageFormatter) is used on the server side.

You'll also need to implement an appropriate ServiceBehavior and OperationBehavior to install the formatter into the stack, but the code for this will be minimal (the bulk of the code will be in implementing the above mentioned interface).

Once implemented, you could use the "one method to process them all" approach to test and debug your formatter. Simply take the received message and dump it out to the console for you to review, and then also send an ebXML response back. You could also use the same approach to build up your unit-testing.

like image 194
Tim Roberts Avatar answered Oct 07 '22 01:10

Tim Roberts