WSSF: ambiguous datacontracts

Hi all,

I’ve been working with Webservice Software Factory (WSSF) for 2 months now and i am pretty happy with this tool. The WSSF provides you with 3 models:

  • ServiceContract
  • DataContract
  • Host

These 3 models can help you with clicking a webservice together. For a nice introduction about WSSF check the following link:

http://msdn2.microsoft.com/nl-nl/magazine/cc164250(en-us).aspx

In this article my colleagues Gerben van Loon and Gerardo de Geest give you a very good first impression of the possiblities of WSSF.

One major thing that’s missing in WSSF is shared types. When you create multiple service contracts based on the same datamodel which is a pretty normal thing to do. Every service that is using the same classes (datacontracts) in the datamodel generates it own version of the class in the proxy.

So Lets say you have Service A and Service B. Both these services use the datacontract Address. When you generate a proxy in the HostModel there will be 2 proxies generated. Both proxies contain the Address datacontract. When you put these proxies in a project “ServiceAgent”, because you want to centralize every proxy in one project you will receive errors because the dataContract Address is ambiguous. 

I think that there are 2 ways to solve this problem:

  • use namspaces
  • generate one central datacontract

Use namespaces
Using namespaces could solve the problem. You can change the namespace that is standard used when you generate the proxy. This means that you should create a new namespace for every proxy you generate. Well i think that namespace should be used to give a good structure to the framework and should not be abused to fix a problem of double generate datacontracts.

Generate one central datacontract
Creating one datacontract which every service can use is ideal, but how could we fix this? When we look at the Host model of WSSF we only have two options:
- Generate Proxy
- Generate Service

If we want to separate the proxy from the datacontract, then we have to change the process for generating the proxy. This could be done in WSSF but if you want to fix this we have to rebuild the whole factory. You could also stop using the generate proxy option of WSSF and create you own generate proxy process with the command-line tool svcutil. This tool provides us with a lot of options to create different kind of objects. We want to create a datacontract (c# file) and a proxy. To fix this it’s important you should use the implementation project Datacontracts within your WSSF solution. This project becomes available when right-clicking on your solution. click Add and then there are 2 WSSF options:

  • ASMX implementation project
  • WCF implementation project

Datacontract

I have selected the second option. When you richt click in your DataContractDesigner you will see an option Generate Code. When your model is valid it will generate the code in 2 of your implementation projects:

  • <name of your project>.DataContract
  • <name of your project>.FaultContract

Because the datacontracts are generated into my implementation project (separated files) i need to build the projects to generate one dll file. This file is important as input for my datacontract and proxy generation. When the dll is available i can generate a file (in my case c#) which will contain all my datacontracts. See the command below:

  • svcutil.exe /dconly <Location of the Datacontract dll>
  • svcutil.exe /dconly <The generated XSD file> /out:<Output location>/n:<Namespace> /s
/dconly The /dconly switch is used to generate only a datacontract.
/out I use the /out switch because i want to define the location where my c# file will be deployed. My output location is the Client application which is also generated when you create your implementation projects. Because my output location is in my Client application i have directly access to my new generated datacontract.
/namespace I use this to make sure that the datacontract will have an appropriate namespace
/s The /s switch is used to make sure that every datacontract will be decorated with the serializable attribute.

The result of the first statement above will be a xsd file, which will be used as input for the second/final statement.

Proxy

Now that we have generated a datacontract we have to instruct the svcutil tool to generate a proxy without generating the datacontracts it uses. This means we have to give a reference to the datacontracts dll we want to use. The statement below is a statement that you can use to fix this:

svcutil.exe <The address of your webservice>  /r:<a reference to the datacontract dll> /r:<a reference to the faultcontract dll> /namespace:<namespace of your proxy> /out:<Output proxy file> /ct:<CollectionTypes>

/r: Used to make a reference to the datacontract or Fault contract dll. You can define multiple reference in on statement
/namespace I use this to make sure that every generate proxy will be in the same namespace
/ct You have to specify the CollectionType datacontracts you have in your datamodel. if you don’t these will still be generate into your proxy. I my example it could be a datacontract Addresses

When you have generated a datacontract and a proxy separately you will never have problems with ambiguous datacontracts.

Regards,

Dennis

 

XML serialization

Hi,

Last week i spend a few hours to analyse and fix a very strange problem. On the project where i am working on right now we have to serialize some objects to XML before we could send it to WebMQ. The objects that need to be serialized are created with the XSD command-line tool. We received an XSD from our customer and generated a class with this XSD.

XSD.exe /c /l:c# <XSD file>

These XSD’s are sometimes huge files so this will generate enormous classes. Before we send our XML reqeust to WebMQ we validate the XML against the XSD to be sure that WebMQ will accept and process our request. At this point i receive messages that the serialized XML isn’t valid, there are some elements missing. I started the debugger and checked if all the values of my object were set before it will be serialized. Everything looks fine, but the XML doens’t contain the values that it put in my object.

When i took a closer look to the XSD file i saw that every property that i have set in my object and isn’t in the XML file has the attribute minOccurs=”0″ defined. So i removed the minOccurs attribute from the XSD, generated a new class again with the XSD command-line tool and tried it again. This time every property was serialized to XML. I couldn’t  believe this was the solution for my problem. minOccurs=”0″ means the least amount of elements that should be in the XML file. So ’0′ is acceptable but ’1′ also. I think the problem is within the XSD command-line tool. The reason this took me so long to fix it, was because first i was looking in the wrong direction. I was searching for ingore and serialazable attributes never thought that the minOccurs in the XSD would be the problem. A colleague mentioned that when the XSD is changed which is my contract to communicate with WebMQ that this could introduce a new problem because my message could be invalid. fortunately this was not a problem i validated my XML against an XSD with the minOccurs attribute and my XML was valid.

Regards,

Dennis

Follow

Get every new post delivered to your Inbox.