A change in mindset is required when switching between a typical CLR application and a web service application. There are some things in a CLR environment that just don’t add-up in a WSDL arena (and vice-versa). I’m listing some of them here. When I say WSDL-world, I’m mostly talking with respect to a WCF Service and / or a Web Service.
No (direct) Method Overloading: You definitely can have overloaded methods in a, say, Console application, but when it comes to a WCF / Web Services application, you need to adorn these overloaded methods with a special attribute so the service knows which specific method to invoke.
When you’re working with WCF, use the Name property of the OperationContract attribute to provide unique names.
By default, the proxy generates the code for this as:
With Web Services though the story is slightly different. Even after setting the MessageName property of the WebMethod attribute, the proxy does not change the name of the method, but only the underlying soap message changes.
The one thing you need to remember is to set the WebServiceBinding accordingly.
The proxy is:
You see the calling method name is the same in the proxy, however the soap message that gets generated is different.
Using interchangeable data types: See details on this here.
Type visibility: In a CLR-based application, if you mark a field as private, well we all know, it’s ‘private’. Coming to a WSDL side of things, in a Web Service, private fields and web methods will not get generated in the proxy.
In WCF however, all your operation contracts will be public as they get implemented from an interface. Even in case your ServiceContract interface is declared internal/private, you will see it as a public interface in the proxy. This is because type visibility is a CLR concept and has no bearing on WCF.
Also if a private field has the [DataMember] attribute in a data contract, it will get emitted in the proxy class as a public property for the very same reason.
See the ‘_x’ field is a private member with the [DataMember] attribute, but the proxy class shows as below:
Passing derived types to web methods / operation contracts:
Once again, in a CLR application, I can have a derived class be passed as a parameter where a base class is expected.
I have the following set up for my WCF service.
The above will throw an exception saying:
In short, this is saying, that a Manager type was found where an Employee type was expected!
Hierarchy flattening of interfaces in WCF:
See details on this here. In CLR world, you’ll see the entire hierarchy as is. That’s another difference.
Using ref parameters:
This one kind of stumped me. Not sure why I tried this, but you can pass parameters prefixed with ref keyword* (* terms and conditions apply).
The main issue is this, how would we know the changes that were made to a ‘ref’ input parameter are returned back from the service and updated to the local variable? Turns out both Web Services and WCF make this tracking happen by passing the input parameter in the response soap. This way when the deserializer does its magic, it maps all the elements of the response xml thereby updating our local variable. Here’s what I’m talking about.
This is how the request and response look like in soapUI.
As I said above, the behavior is quite similar for WCF as well. But the catch comes when you have a one-way web methods / operation contracts. If you have an operation contract whose return type is void, is marked one-way and that has ref parameters then you’ll get an error message when you try to reference such a service.
This is what I got when I did an update to my service reference:
Makes sense, because a OneWay operation is… one-way – there’s no returning from this operation. You can also have a one-way web method:
This will throw an exception message similar to the one above when you try to update your web service reference.
In the CLR space, there’s no such concept of a ‘one-way’ street! Yes, there’s void, but you very well can have ref parameters returned through such a method.
Just a point here; although the ref/out concept sounds cool, it’s generally is a code-smell. The better approach is to always return an object that is composed of everything you need returned from a method.
These are some of the differences that we need to bear when dealing with services that are different from our daily ‘CLR’ life.