I have read several posts about WSDL and SOAP but still I'm confusing the actual meanings of those terms. Now, I understand that you need to construct a request message in order to consume a webservice, would it be post or get message. When talking about SOAP based webservices, you need to communicate with a webserver via constructed XML documents that are SOAP compliant. So, you need to build that manually or using proper libraries. What about WSDL, when this thing comes in?
Wikipedia states "WSDL is often used in combination with SOAP and an XML Schema to provide Web services over the Internet. A client program connecting to a Web service can read the WSDL file to determine what operations are available on the server.". So that means that WSDL is just some file describing what services are available on webserver, and I guess, such communication must also be done using SOAP. But if I know all the webservices I use, I mean, if they are hardcoded then that means that I'm not dealing with WSDL at all. IMHO WSDL is just for very smart systems where before using webservices a program needs to read status and determine what to read. Am I right?
WSDL is a means to describe what operations (method) the webservice has as well as the input/output of those methods. In the past, way before the mobile becomes popular, WSDL is used as a means for creating what is known as a stub/proxy classes.
These classes is basically generated by specific Generator (such as WSDL2Java for Java or WSDL.exe for .NET) whose job is to read the WSDL, get the methods along with its input/output and generate a language specific classes to expose those services natively. In effect, it is hiding the SOAP messages from the user and the from the consumer of the webservice point of view, they are dealing with the native classes of their language of choice.
WebService with SOAP thus was heralded as means of integration between heterogeneous systems, allowing a communication that is language independent. For example the language for implementation for the service could be in C# but the consumer of the webservices can be in Java. If the consumer is Java programmer, by using the WSDL to auto generate the classes, the Java programmers don't even need to know the concept of SOAP or XML. All the programmers know that they are dealing with Java object.
Nowadays, SOAP is more transparent and well known than it was in the past. As a result, by choice programmer can directly code the SOAP message, bypassing the need to generate the code via WSDL
Related
We are migrating our .net Remoting app to use WCF. One thing that confuses me now is the concept of "Known types" that WCF introduced but not needed by Remoting. While I am sort of understand what the known types are and what they do, what I am confused about is the difference between WCF and Remoting - On the sender's side, if WCF doesn't have enough type information about the object at hand to serialize it, why does Remoting? Same for the receiver: Why .net Remoting doesn't have a problem deserializing an object received but WCF does? Is that because Remoting sends metadata along with the data? If so why can't WCF do the same?
You're correct - .NET remoting sends type metadata with the requests. WCF can do the same, but by default it doesn't - it's a lot of extra information which makes the requests larger and more complex to process (affecting performance). Not sending the type information also allows for loosely coupled systems, where the client and the server can version separately, and as long as they adhere to the contracts established in the original version, they will continue working. And it also allows for WCF to talk to systems written in non-NET platforms (which isn't possible with remoting or other technologies which rely on shared type information).
If you really want to go with the non-known-types way, you can replace the default serializer used by WCF (the DataContractSerializer) with the NetDataContractSerializer, which will send type information with each request. To use that, search for "wcf netdatacontractserializer" and you'll find how to use it.
I have a WSDL file from a published ASMX web service. What I am after
is creating a mock service that mimics the real service for testing purposes.
From the WSDL, I used SvcUtil.exe to generate code. Apparently it also generates
the server side interface.
Well the issue is that it generates very chunky interfaces. For example, a method
int Add(int, int) is showing up in the generated .cs file as AddResponse Add(AddRequest). AddRequest and AddResponse have a AddRequestBody and AddRequestResponse and so on.
The issue is that, to implement, I need to create the body and response instances for each method, even when I just want to return a simple int result.
Why can't it generate the method signature properly? Is there a better way of generating WCF Server side interface/contracts from WSDL?
The message structure you are describing is caused by two things:
better interoperability across web service stacks and their programming models (RPC vs messaging);
flexibility to accommodate new parameters into existing web services.
You are not the first one to complain about it, or the last. It's a WSDL binding style commonly called the document/literal wrapped pattern. It produces document/literal web services and yet also supports an RPC programming style. It's very "WS interoperability friendly", so to speak...
The WS-I Basic profile specifies that the soap:body must have only one child element and in this case it's a wrapper for the operation name that's being invoked. The parameters of the call are packed into only one element as a best practice since it's more flexible to later changes. In case of WCF you usualy end up with a MessageContract which has one MessageBodyMember which wraps all the parameters.
Basically, you are seeing the results of web service battles fought long time ago.
Here is some extra reading on the subject (and that's just the tip of the iceberg):
Which style of WSDL should I use?
RPC/Literal and Freedom of Choice
My Take on the Document/Literal 'Wrapped' Idiom
How do I go about making sure that my WCF service can be accessed from any other language(Java, PHP, whatever iOS uses, etc.)?
I have kept everything as httpbinding plus not used any of the .net roles/membership authentication for the clients. But there are some things that I am not sure of. Like, can I return a generic List that is readable by those other languages?
Any of the WCF bindings that don't start with net (netTcp, netMsmq etc.) should be fine - they're designed to be interoperable.
The most basic one is basicHttpBinding which is pretty much plain HTTP - nothing much can be added to it. You should be able to call this from any scripting language (PHP etc.).
The more advanced binding is wsHttpBinding which implements lots of the WS-* standards and can be called from other languages where the networking stack can handle WS-* - stuff like Java etc.
And then there's the webHttpBinding which exposes your service not via SOAP, but via a REST endpoint. This should be callable from just about any language, any device, any place.
And of course, you get the best coverage if you expose multiple endpoints from your service, offering a variety of choices to anyone trying to call you. All this is done simply in config - no code change necessary to support multiple endpoints, multiple bindings etc.
As for lists and stuff: WCF exchanges serialized messages - basically XML - which is governed by a XML schema. The combination of a WSDL and XSD is totally interoperable and can be understood by a wide variety of other languages.
A List<T> in .NET will be turned into an array in your XML structure, and that's totally interoperable - don't worry. The client might just get back an array instead of a list - but that's not a problem.
The only problem is that you cannot really model a generic list, since the XML schema doesn't support generics - you need to be explicit about what it is you're sending back. A List<T> won't work - a List<Customer> will (if your Customer object is part of your data contract and marked as such)
You cannot be 100% sure if you don't have any control over the client technology that is used to consume your services. But you can be very confident if your web service (WSDL) conforms to the WS-I basic profile v1.1. This standard is very widely supported and mature. You can use the excellent SoapUI test tool to test your WSDL for conformance.
Is sharing a project containing the wcf interface and datacontracts and using these via ChannelFactory to consume the service against SOA principles?
My architect is advising that generating a proxy using Add Service Reference is preferable.
I guess that depends on a some things: your infrastructure, security policies, governance, etc.
We design our WSDLs (service and message contracts) and XML Schemas (data contracts) and then use svcutil.exe* to generate a proxy. At that point, we have code we can either use to consume or stand up a service. Of course, I am just talking about the code, the output.config will be modified with proper behaviors, bindings and endpoints as those are decided.
Once the service is stood up, it's fronted by an XML gateway. At which point we can begin testing the services using the 'Add Service Reference...'. If you're just looking to save some time and hand someone else your pre-generated proxy or your WSDLs aren't exposed (as they're behind an XML gateway that does not echo them), then what you're doing seems fine.
Otherwise, I'd expect consumers to be able to 'Add Service Reference...' and generate their own clients.
*Java-based applications use something else (WSDL2Java/ClientGen/built-in IDE tool).
Sharing pre-packaged service interfaces along with datacontracts isn't against SOA principles as long as consuming services are not expected to use it. This is exactly what enables potential clients to speed-up development against an existing 3rd-party service, or begin development against one which is yet to be built. Providing interfaces/datacontracts in code format will be less ambiguous than describing these things via documentation only (of course they may not be useful if the client is using a different programming language).
However, if some sort of pre-packaged implementation of the service interface is provided in the shared package, and this implementation is required to be used to successfully use the service, then this would be against SOA principles unless an implementation was written for all types of clients. Being pragmatic though, this can be a good idea so the clients can be more loosely coupled against things such as transport choice, service contract changes and service versioning.
I would recommend using the ChannelFactory (from a dotnet client of course) whether consuming the services via a shared pre-packaged interfaces/datacontracts project or dll, or generating your own proxy (via 'Add Service Reference' or 'svcutil.exe'). This will allow you to code against the service interface and therefore your client will be much more friendly to using concepts such as dependency injection for stubbing, testing, etc.
Both methods of generating a proxy are valid, it depends on how much control you wish to have over the proxy, and if you own both sides of the code. A third option also exists, you can hand craft your own proxy. Let me explain further:
In SOA we pass messages, this is a different paradigm to passing pointers to objects on a heap/stack which is the norm in OO world.
Thus in SOA, the contract (what you can do) and the message (the state to act upon) are important and need to be shared with the consumers of the service so they can all agree on the contract or "rules of engagement" here we have the most basic form of SOA.
Enter WS-* a set of specifications for adding more functionality to our service call (distributed transactions, security etc...) but if we do this we all need to agree on the rules and the flavor of the type of interaction we intend to use, so the service and its clients need to agree exactly on how this is to occur so it to needs to be shared.
The combination of the contract definitions and WS-* specifications is called a WSDL and this typically is what get shared between clients and services, this is in line with the SOA tenants that we share schema and contract, not class, and that Compatibility is based on policy (WS-*).
So if you use channel factory you generate the proxy based on the interface definition you have and the config you have set up on the fly, if you use add service reference you let the IDE generate a proxy class based on the WSDL of the service as it exists then.
If you hand craft the proxy, you have full control over how this happens and you can jump into the interception chain and do things on the client side to manipulate the call.
Depends on what you want to do.
The standards we have carefully considered and adopted at my company, are that we distribute service contracts is two ways. As a shared assembly when delivered to teams within the company, and as a WSDL when providing to clients and other third parties. It is a standard we discussed with Microsoft during a design / process review and they agreed was the correct approach.
Does anyone know of any problems with using WCF to expose a SOAP interface for non .NET clients? For example incompatibilities with other SOAP libraries?
This is so that the SOAP interface can be exposed for third parties to integrate with our software.
Some of the problem areas I've encountered with WCF:
It generates WSDL that is split
across multiple URLs. That is, one
part of the schema is at one URL,
another is at a different URL, etc.
The "main" WSDL URL (the one with
just "?WSDL" after the service name)
references the others via xsd:import
elements. Many SOAP clients (eg pre-.NET Delphi) have enormous difficulty with this idiom. So you really have to "flatten" your WSDL in order to achieve interoperability in practice. One solution is given here.
WCF doesn't generate XML namespaces
the same way as, say, ASMX web
services. WCF has a tendency to
place any service or data contract
into a namespace of its own
choosing. Again, some SOAP clients have difficulty with this. You can increase you interoperability level by adding an explicit namespace to your ServiceContract and DataContract attributes.
Many SOAP clients won't handle
faults as nicely as WCF clients. For example,
the proxy generation code won't
create client-side objects for the
faults declared in the WSDL. The
faults will still be transmitted to
the client, of course, but the
client then has to do more work to
figure out what kind of fault it
was.
versions of the WS-* standards stack can also be an interoperability issue - for example the version of WS-Addressing (2003) supported by some java implementations eg Oracle BPEL is not supported by WCF which supports the later draft and 1.0 versions but not the earlier 2003 one
Generally everything works fine. It will obviously depend on the client you're using - not everyone implement SOAP properly.
P.S. Could you please rephrase your question if you hope for more specific answer?