Hi Greg, On 10 July 2015 at 19:00, Greg Keogh <[email protected]> wrote:
> Folks, we have a WCF basic http binding service that has been in > production use for many years, but so far the only clients have been .NET > desktop and Sliverlight apps. They can of course use a proxy class > generated by svcutil.exe and it's all easy peasy. > > Now the time has come to open the service up to other clients such as apps > on phones and tablets written in Objective-C, Swift, Java and perhaps > JavaScript. We haven't had any of these clients consume our service yet, > but it may only be weeks away. A Java guy told me that if he has the WSDL > then it won't be a problem, but I fear there may be devils in the details. > I quite worry that the svcutil generated code contains stubs of all C# > classes that are public in the service and can't imagine how they would > transformed for consumption by different clients. > I'm not sure what you mean here. The generated C# is useless to everyone else anyway. WSDL is just a fancy XML schema and Mr Java will feed it into his equivalent of svcutil to generate POJOs. Mr Swift will do likewise. Your WSDL is presumably generated from the DataContractSerializer attributes on your data contracts and the WCF attributes on your service contracts. Remember that DCS and WCF are all about contracts, not classes. CORBA, Protocol Buffers, Thrift, you name it, are no different. The fact that your contract specification happens to be grafted onto a class is irrelevant to svcutil. You could just as well have written the contract as an XML schema. It's not that svcutil is generating a "stub", but rather it is generating classes that completely implement the contracts, and nothing more. If you put extra code in your classes, DCS and svcutil ignore it. Code can never be part of a web service contract. It sounds like you may have added additional functionality to your data contract classes and are sharing that assembly between the Silverlight client and the service, hence your view that svcutil is generating "stubs". Doing this effectively blurs the separation between tiers, causing UI code to appear in the service and database code to appear in the UI. If your application has as many tiers as it sounds, maybe you should demote these classes to pure POCOs (literally, not in the EF sense!) and not re-use them in multiple tiers like this. That way, your data contract classes are for communication between your service tier and client tier only, as it should be. If the Silverlight UI needs additional functionality, it should be using its own model designed for its needs. Subclassing the original POCOs is one way to do this, although personally I prefer a clean separation and create fresh models and translate between them. By the way, you shouldn't need to use svcutil for code generation if you are writing your services contract-first, by which I mean WCF-interface-first, not WSDL-first. If you have already written a service contract IApi, just create a client class derived from ClientBase<IApi> [1]. Then expose the inner proxy, re-export some constructors and you're done. I find that this takes less time than properly integrating a svcutil code generation step into my msbuild files. Then again, I don't know anything about Silverlight except that a lot of things are missing there, so you may have a good reason for doing this. I fear that our SOAP style service is too specific and old fashioned to be > easily consumed by non .NET clients. I'd be interested to hear if anyone > can confirm this or has general comments in this area. I'm guessing a REST > style would be best for everyone, but what will it return, XML, JSON, or > both? > Publishing your service with a REST API sounds like the right thing for the future. Many modern REST frameworks appear to emphasise JSON. I have come across a few REST services that only understand JSON, e.g. CouchDB [2] and RabbitMQ [3]. I would pick JSON if your project is young. Still, by going with BasicHttp(s)Binding, you may have accidentally made things very easy for your non-.NET clients. Since WCF includes this binding for compatibility with the ancient ASP.NET XML web services infrastructure [4], all the foreign WSDL tools should work as long as you stay away from WCFisms. As a last resort, your Java and Apple friends can even write a client access library for your service by hand using just an HTTP client and an XML library. I recently did this in Haskell, enough for a Haskell process and .NET process to call each other's service actions. It turned out to be surprisingly easy, and not just because Haskell is an exceptional programming language ;). Let me know if it comes to this and I'll tell you what you need to do to get "HTTP client + XML library = WCF BasicHttp(s)Binding client", in language agnostic terms of course. Don't count on this option if you plan to move to a different WCF binding. Last year I spent a whole weekend trying to coerce the Web API to respond > with XML shaped the way I wanted, and I eventually gave up in disgust as > the plumbing sprang leaks and tangled with itself and I wrote a raw ashx > handler which did all the work manually, and it was easier to read and > maintain. I recall you also had issues with unwanted XML namespace declarations. XML namespaces are one thing that I think you will just have to accept because they are a fundamental part of XML and not optional if you want to use anything to do with XML schemas, including WSDL. Properly-namespaced XML can potentially save you a lot of confusion in the future. If anything, having XSDs will enable IntelliSense, code completion and schema validation in the Visual Studio XML editor. [1] https://msdn.microsoft.com/en-us/library/ms576141.aspx [2] http://docs.couchdb.org/en/1.6.1/api/basics.html [3] http://hg.rabbitmq.com/rabbitmq-management/raw-file/rabbitmq_v3_3_4/priv/www/api/index.html [4] https://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpbinding.aspx -- Thomas Koster
