I’m still messing around with WCF and right now playing with accessing a variety of Web Services through a WCF client and then feeding the result back through COM Interop to an unmanaged application. There are a couple of disturbing things happening when using the default SvcUtil Web Service import functionality with Web Services depending on what type of methods are available on the existing ASMX Web Service.
I have a Web Service that includes a couple of support methods that allow passing in of DataSets by the client. The DataSet methods are optional and are meant only for an older application using FoxPro that passed this data. Since that app’s not used any more I thought I can safely get rid of that service method and remove the DataSet.
The single method looks like this:
[WebMethod(Description="Allows uploading of an invoice to the server using DataSet objects")]
public bool UploadInvoice( DataSet InvoiceDataSet )
What’s bizarre is that having a method in the service that returns or passes a DataSet drastically changes with SvcUtil generates. I’ve had lots of problems with consistency in this scenario and removing the DataSet method changed the behavior of the client overall.
A few things happen:
- With the DataSet in the Web Service signatures I’ve had problems where SvcUtil will generate duplicate classes of the various message objects (ie. any complex parameters or return value types). It will double generate them. It’s inconsistent though – I have it working now but earlier today, with the same code SvcUtil would always generate duplicate message classes that I manually had to remove.
- With no DataSet in the class the signatures bloat turning the simple operation signatures into complex Request/Response messages. Right – the Web Service proxy classes get much larger WITHOUT the DataSet in any of the signatures!
The code generated states in a comment that SvcUtil must generate a Message Contract because the parameter type is not nillable. Whatever that means <s>. Check out these two generated classes below. The first one includes a single method that has DataSet input parameters. The second removes this method:
Quite a difference for REMOVING a single method to the service, huh?
- Finally I’m using COM interop to let an unmanaged application access the Web Service. Since complex types are involved letting .NET do this is preferred vs. using the SOAP Toolkit or a custom solution that would involve manual XML parsing.
So I’ve been passing the Proxy (the created Client instance) back over COM Interop to the client app and that works – the app sees the proxy and the service methods. However when I have the second scenario above (no DataSets) the Proxy methods don’t take simple parameters, but rather use Request/Response messages as parameters. In .NET this works correctly as the Client instance overrides the SOAP interface, but over COM the SOAP interface gets returned resulting in unusable parameters on the client. If I switch back and include the DataSet method again and regen the proxy, then everything works correctly – I get the proper method signatures all the back to the unmanaged client.
All of this makes me very nervous as it seems to be very inconsistent behavior. The SvcUtil hiccups, the odd behavior related to operations that include datasets (which incidentally looks to work BETTER than without them!) is not exactly confidence inspiring.
Granted this is a really fucked up scenario – COM Interop certainly is not terribly common anymore. DataSets are generally frowned upon in Web Services and for good reason. OTOH, I had a good reason to use them here because of interop concerns and they are used optionally. But I’m not sure I understand the behavior that occurs when the DataSet is removed from the Web service – that seems very backwards to me.
I suspect things are much smoother with using WCF to WCF operations which will become more common as time moves on, but right now I wonder if we’re not better off sticking to stock Web Service clients over WCF for pure Web Service front ends. At the end of the day – although more flexible – WCF is a bit more complex than using Web Service proxies and apparently more verbose. But looking forward I’m pretty sure that WCF will be the way to go and this is why I find myself here experimenting to see how things will go with these internal play services…