Data Representation in Windows Communication Foundation
In This Chapter
- Background
- XmlSerializer and XmlFormatter
- The XML Fetish
- Using the XmlFormatter
- Exception Handling
Background
The Windows Communication Foundation provides a language, called the Service Model, for modeling software communications. Software executables can be generated from models expressed in that language using the classes of a lower-level programming framework called the Channel Layer.
In the language of the Service Model, a piece of software that responds to communications over a network is a service. A service has one or more endpoints to which communications can be directed. An endpoint consists of an address, a binding, and a contract.
The role of the address component is simple. It specifies a unique location for the service on a network in the form of a uniform resource locator.
The binding specifies the protocols for communication between the client and the server. Minimally, the binding must specify a protocol for encoding messages and a protocol for transporting them.
A contract specifies the operations that are available at an endpoint. To define a contract, one merely writes an interface in one's preferred .NET programming language, and adds attributes to it to indicate that the interface is also a Windows Communication Foundation contract. Then, to implement the contract, one simply writes a class that implements the .NET interface that one has defined.
This contract was used to define the operations of a derivatives calculator service in Chapter 2, "The Fundamentals."
using System; using System.Collections.Generic; using System.ServiceModel; using System.Text; namespace DerivativesCalculator { [ServiceContract] public interface IDerivativesCalculator { [OperationContract] decimal CalculateDerivative( string[] symbols, decimal[] parameters, string[] functions); void DoNothing(); } }
One way of writing code for a client of that service that is to use the CalculateDerivative() operation would be to write this:
string[] symbols = new string[]{"MSFT"}; decimal[] parameters = new decimal[]{3}; string[] functions = new string[]{"TechStockProjections"}; IDerivativesCalculator proxy = new ChannelFactory<IDerivativesCalculator>("CalculatorEndpoint"). CreateChannel(); proxy.CalculateDerivative(symbols, parameters, functions); ((IChannel)proxy).Close();
When the statement
proxy.CalculateDerivative(symbols, parameters, functions);
is executed, the data being provided by the client as input to the operation is added to an instance of the Message class of the Windows Communication Foundation's Channel Layer. Within the Message class, the data is represented in the form of an XML Information Set (InfoSet). When the data is ready to be transported from the client to the service, the message-encoding protocol specified in the binding will determine the form in which the Message object containing the data provided by the client will be represented to the service. The message-encoding protocol could conceivably translate the message into a string of comma-separated values, or into any format whatsoever. However, all the standard bindings specify encoding protocols by which the Message object will continue to be represented as an XML InfoSet. Depending on the encoding protocol of the binding, that XML InfoSet may be encoded either using one of the standard XML text encodings, or the standard MTOM protocol, or using a binary format proprietary to the Windows Communication Foundation.
When a transmission is received by a Windows Communication Foundation service, it is reassembled as a Message object by a message-encoding binding element, with the data sent by the client being expressed within the Message object as an XML InfoSet, regardless of the format in which it was encoded by the client. The Message object will be passed to a component of the Windows Communication Foundation called the dispatcher. The dispatcher extracts the client's data items from the XML InfoSet. It invokes the method of the service that implements the operation being used by the client, passing the client's data items to the method as parameters.