Multiple web service references sharing types
In this article I would like to point out a useful way to accomplish something that would be really easy, but still have been annoying me for the last couple of months. Imagine that you would like to get some data of some type from one web service and pass it on to another. The data types on both server sides are the same, but the compiler won’t let you pass the type from the first service on to the next one. Casting won’t work either, not without implementing some kind of home made casting method.
This is really really annoying, since the scenario stated above is really common in the web service world. I will present a solution to this, using the wsdl command line tool when adding web references instead of the built-in tool in Visual Studio.
The scenario
I will present more details on the scenario stated above, by giving a simple example. There will be three web services, one holding some articles and two others that will be fed with some of these articles to calculate the weight based on the density and the volume of the article. Let’s say that the articles are different kinds of box shaped things.
The scenario looks like below:

- The WeightCalculator requests articles from the Article owner.
- Based on the type of an article the WeightCalculator passes on the article on to the right calculator for that specific type.
- The selected Calculator for the article type returns the weight.
- The WeightCalculator sets the weight and sends the article back to the owner.
The Article class looks like below:
public class Article
{
public string Id { get; set; }
public string Name { get; set; }
public ArticleCharacteristics Characteristics { get; set; }
}
public class ArticleCharacteristics
{
public double Length { get; set; }
public double Height { get; set; }
public double Width { get; set; }
public double Weight { get; set; }
}
All three web services handles these types.
The regular way to do it
In most cases a web service consumer, the WeightCalculator above, consumes web services handling different data types. In the scenario presented above all three web services will use the Article class as parameters and return values. Using Visual Studio when implementing this makes it easy to add web references:

This is the easy way to gain access to the services to consume. The drawback with this solution is that the services will have there own version of the Article class, meaning that just passing an Article object from one service to another involves creating a new instance of an Article using the receiving service’s version of the Article. This means that the code below will not work:

As you can see, the compiler complains about the GetWeight method call. The TypeACalculator has its own Article type and the same things goes for the TypeBCalculator. This means that you have to create a new instance of the article to be passed to the TypeACalculator or TypeBCalculator, like below:

The compiler WILL NOT accept casting the ArticleOwner version of the Article type to TypeACalculator or TypeBCalculator version of the Article type.
As you can see there is more or less a huge amount of code to write to pass the article on to the TypeACalculator, even though the Article class is not so complex.
There has to be a solution to this! Let’s have a go…
The better way to do it
There is a much better way to do this, meaning there will be much less code to write but you have to use the command line wsdl tool.
In the regular way described above the web service references were added using the “Add service reference…” menu in the solution explorer in Visual Studio. This, the better way to do it, uses the wsdl command line tool that comes with the .NET Framework 2.0.
The wsdl tool has the “sharetypes” option, meaning that if the tool is fed with more than one web service URL, all types are compared and identical types will be shared among the web services.
In this scenario the command will look like this:
wsdl /sharetypes \ http://localhost:53946/Articles.asmx \ http://localhost:53952/TypeA.asmx http://localhost:53953/TypeB.asmx \ /out:ServiceProxies.cs /n:Articles
The /out option means that the generated code for the service proxies will be placed in the named file, ServiceProxies.cs, and the /n option makes the types to be placed in a namespace, Articles in this case.
Articles.asmx is the ArticleOwner web service, TypeA.asmx is the TypeACalculator and TypeB.asmx is the TypeBCalculator.
Please note that the above command has to be written in one line!
All you have to do now is to include the generated file in the project that will consume the web services referenced. Let’s look at the code now, to perform the same operations as in the example above:

In this case the Article class is shared between the ArticleOwner and the TypeACalculator and TypeBCalculator, since the types look exactly the same. The wsdl command line tool makes a really nice work with types like this.
The Article object in the foreach-loop will be accepted as parameter to the TypeACalculator since the type is shared between the ArticleOwner and the calculators.
The sharetypes option passed to the wsdl command line tool makes it easy to consume many web services using the same types.
Notes
Please not that the code examples above show only the use of TypeACalculator, but of course the same goes for the TypeBCalculator.
The Article class shared among the web services will be accepted as parameter to a SetArticles method on the ArticleOwner web service.
If the endpoint address for an instance of any web service client proxy is not changed, the URL given to the wsdl tool will be used. This is exactly the same when adding a service reference using the menu option in Visual Studio.
Further more
In an upcoming article I will present a way to make the procedure stated above even easier by generating an interface for the web services to implement. This is a nice way when dealing with many web services that will expose the same methods handling the same types of parameters.
Read more
Read more about the wsdl command line tool on MSDN:
http://msdn.microsoft.com/en-us/library/7h3ystb6.aspx.
[...] a previous article, Multiple web service references sharing types, I wrote about sharing types between referenced web services. That article used the old ASP.NET Web [...]
Sharing DataContracts between WCF Services at freddes.se
2 May 10 at 17:21