February 2010 Entries

Imagine a huge BizTalk-project. Loose coupling has been taken very seriously and a lot of this is done via the MessageBox and subscriptions. Very complex workflows are distributed over lots of Orchestrations. Commands in the messages tell the system which Orchestration to call next, which backend-system to call, etc. Nice... :-)

Then one day during developer-testing something strange happend. We started a process with Command_A. We inspected the progress of our Workflow-Armada in DebugView. It started out normally like "Start processing. Command_A". Then the next Orchestration started and it was the wrong one: "Start Processing. Command_B", but we expected it to be Command_Y! But it started getting better: After processing the wrong Command_B the Orchestration to cal the backend-system started and told us: "Invalid Command: Command_C". Our first reaction was: "What!?!?!". We spent a long time searching where the wrong commands were set, examining all Orchestration-paths and helpers. Nothing. It should have worked. We took another test-system. It worked as expected, but we were able to reproduce the strange behaviour on the main-system.

After a while the penny dropped: The commands were defined in an Enum. We thought we were fine, because we added numbers explicitly to the commands (like Command_A = 456). But someone had included new commands just in the middle of our existing commands without definfing numbers. So the index of the enum was not correct. We had to recompile the whole lot (enums are included in the IL of the classes using them) and it worked again. What a day... ;-) 

 

It happens once in a while (to me at least):

You get an XML schema and your task is to create a WCF service that accepts this data as parameter or uses it as return value.

So you generate a class from the schema using xsd.exe (like "xsd XMLSchema1.xsd /c /l:CS /n:mipsen.schemas"). You create your ServiceContract and implementation (adding ServiceKnownType to avoid funny behaviour concerning the schema-generated class), create the web.config and svc-file and host your service (in IIS, for example). You are done.

Then someone creates a reference to your WCF service to call it in his or her code. When using the generated class of the parameter or return value something happend to the names of the fields: they are all named [fieldname]field, like elementQfield, instead of just ElementQ. The slightly confused colleague comes over and asks what happend.

WCF uses the XmlObjectSerializer by default to handle serialization of the data contracts. If you use XML based data contracts you might consider using the XmlSerializer instead. The fields in the reference will be named as expected.

More information abot using XmlSerialzer can be found here

To tell WCF to use XmlSerializer you can apply the attribute [XmlSerializerFormat] to the operation or even the service in the interface.

Example:

[ServiceContract(Namespace="http://somenamespace.com/contracts")]   
    public interface ISchemaService
    {
        [OperationContract]
        [XmlSerializerFormat]
        void DoSomething(GeneratedType data);
    }

Why am I writing this? It might be a pretty obvious thing to WCF-experts. But when it first happend to me some time ago it took me a while searching the internet (without success) and trying different things until I found the right way...