WCF - Transfer and Data Encoding

One of the greatest benefits of Web services has in relation to distributed communication technologies is the use of XML as the basis for coding, thus allowing interoperability between various platforms. However, the choice of the coding standard and how to transfer this information to be adopted by service greatly influence the performance and interoperability of the same and also those who consume it. WCF - Windows Communication Foundation - provides some techniques and alternatives that we can adopt during configuration or creating a service. The purpose of this article is to show how to implement such a configuration / design and analyze the impacts (including the level of contract), benefits and limitations of each of these techniques. When we design a contract for a service, we define some methods to meet business rules he intends to do. By default, for each method created, WCF creates two versions of this method (more popularly known as posts) for one request (Request ) and another for response ( Response ). Each message is represented by a SOAP envelope that, in turn, contains a header ( header ) and body ( body ). While the header provides information about the security, correlation, context, etc., the message body is responsible for containing the data being sent to a service or when a service response is being returned to the client. Information contained in the header can be used by the final recipient as well as some intermediate, if any. Further, the contents of the message body, for conversion must be used by the last recipient, or rather the final recipient, regardless of how many firewalls or routers exist. When we have a contract that exposes methods that receive or return simple data types, such as strings , numbers or even complex objects, but also provides simple properties, we do not see many problems in terms of performance. The problem starts to appear when the service that we are designing will accept a "heavier" content, such as files, images, multimedia, etc. In this case, if we neglect us some details, we can suffer penalties on service performance. Default Text (Structured Text) is to encode the data in a readable format, so it is possible to read its content in any editor text, and any system will be able to process such text. With the standard Text , and each item is wrapped in an element or attribute data "non-text" will be converted to text before being sent, contributing to increase the size of messages that travel across the network. For easier service, the overhead is minimal. But what about when we need to transfer large amounts of data, such as: images, multimedia, etc.(Represented by array of bytes ?) The current behavior of the WCF makes it apply encoding Base64 to a binary content if we wish to continue using the format Text , thus resulting in a more compressed text but nonetheless still be a very content higher compared to its original size. Moreover, the parser of the XML does not work very well with extensive content, which may result in problems during runtime . In situations where the binary content is a requirement and no need for interoperability (where client and server make use of WCF) , we may resort to the use of the binary encoding, which is used in all the bindings for use in homogeneous environment. We'll talk more about the types of coding and bindings in section Encodings , a little further down. Finally, we have yet a third alternative that is MTOM ( Message Transmission Optimization Mechanism ), which is the same standard used when we send an e- Email a binary content. This open standard governed by the W3C , instead of encoding the binary content as Text , it is sent intact as an "attachment" message, following the specification of the standard MIME ( Multipurpose Internet Mail Extension ). As before, any original message text will be encoded as an XML Infoset , but the binary content is represented as a reference, pointing to the MIME attachment. When the message arrives at its destination, the runtime WCF is able to reconstruct the original message from the SOAP envelope and their "attachments." When we make use of MTOM, WCF is able to determine the size of the message and if it is too small, rather than making use of MTOM, he chooses to encode the message using the encodingBase64 . But when the content is great and the WCF will see that benefits from the use of WCF, it will create a new MIME section and place the binary content and there, in the SOAP envelope, we have a reference to such content. The image below illustrates the use of MTOM:
















Figure 1 - The externally MTOM defines the binary content.

An encoding within the WCF defines the rules of how data encoding is performed, or rather the message.Messages ( Request and Response ) are represented within the WCF infrastructure through a class called Message. We have another important element within the runtime WCF called encoder , which is nothing more than an implementation of a particular encoding and that will do different tasks depending on the moment, namely: the sender side, the encoder is responsible for retrieving the instance class Message , turn it into a stream of bytesand send it to the destination through the network; since the receiver side, the encoder captures the sequence ofbytes from the network and turns it into an instance of class Message again, so that it can be processed. All coding standards ( encoding ) that we mentioned above are strongly related to Binding and, therefore, that it is a setting that can be performed without interfering in the creation or implementation of the contract. Each of the bindingsdefined within the pre-.NET Framework already has an encoding specific. The table below illustrates the four options (classes) and that we have talked about above:
EncodingDescription
TextMessageEncodingBindingElementThis encoding is the default for all bindings based on HTTP and is also suitable for all custom you will create and require interoperability.Remembering that this encoding reads and writes content based on the SOAP 1.1 / 1.2 format, format Text without any specific treatment for binary content.
MtomMessageEncodingBindingElementThis encoding provides a major customization to the binary content and is not used by default in any binding .
BinaryMessageEncodingBindingElementThis encoding is the default for all bindings * Net and is ideal for when the communication is involving WCF on both sides (client and server) choice. This encoding uses the format NET Binary XML , which is a binary representation for the Microsoft XML Infoset .
WebMessageEncodingBindingElement *This encoding enables the encoding format in plain-text XML and JSON ( JavaScript Object Notation ). This type of encoding is commonly used when you need to expose the service consumption via POX, REST, RSS and AJAX.

Figure 2 - Hierarchy of encodings .
BindingEncoding
BasicHttpBindingTextMessageEncodingBindingElement
WebHttpBinding *WebMessageEncodingBindingElement *
WSDualHttpBindingTextMessageEncodingBindingElement
WSFederationHttpBindingTextMessageEncodingBindingElement
WSHttpBindingTextMessageEncodingBindingElement
NetTcpBindingBinaryMessageEncodingBindingElement
NetPeerTcpBindingBinaryMessageEncodingBindingElement
NetNamedPipeBindingBinaryMessageEncodingBindingElement
NetMsmqBindingBinaryMessageEncodingBindingElement

Now that we know what are the encodings defined as standard for each of the bindings exist, we need to understand how to proceed to customize and / or change the encodings of bindings exist. All binding directly or indirectly inherits from a base class called Binding . This class provides also abstract method calledCreateBindingElements , which provides a collection as a return type BindingElementCollection . The purpose of this method when overridden in derived classes ( BasicHttpBinding , NetPeerTcpBinding , etc.), is to return a collection containing all elements (security, transaction, coding, etc.) that make up the binding , configured properly and in the correct order. To alternarmos between coding standard Text or MTOM, we can resort to property MessageEncoding , which accepts as a parameter of the items specified by the enumeratorWSMessageEncoding . The code snippet below illustrates how to perform the configuration of a specific binding to support MTOM format.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;

BasicHttpBinding b = new BasicHttpBinding ();
b.MessageEncoding = WSMessageEncoding.Mtom;
Important Note: The property MessageEncoding is available only for bindings that support interoperability, as is the case with bindings HTTP. As mentioned above, the other bindings are useful and have a better performance in totally homogenous environment. Customization in coding we did through the above code is also supported at the configuration level. For each of the encodings there is a corresponding element that we can use when configuring the binding in the application configuration file. The elements are: <textMessageEncoding /> ,<mtomMessageEncoding /> , <binaryMessageEncoding /> and <webMessageEncodingElement /> . It is important to remember that the same type of encryption that will be used on both sides, otherwise, an exception of type ProtocolException will be thrown. Finally, you can resort to the technique of logging (already addressedin this article ) so you can view / intercept the generation or reading the message content and analyze its encoding. The image below illustrates the same content being trafficked in a normal format ( Text ) and then making use of MTOM.



Figure 3 - Differentiating the coding standard used.
Ways to Transfer 
Once we have determined what will be the binding and the encoding to be used for the service, we now need to understand the possible ways of data transfer and how to incorporate them into service. It is important to say that the features discussed here are not valid for all bindings ., and that in the course of this section, we will see how and where we can apply these techniques WCF supports four modes of message transfer (options enumeratorTransferMode ):




using System;
using System.IO;
using System.ServiceModel;

[ServiceContract]
public interface IImagens
{
    [OperationContract]
    Stream Download (string imagemId);

    [OperationContract]
    string Upload (Stream image);
}
As we can see, the way we design the contract changes drastically. Its implementation will have to know how to deal with the Stream ; in the case of the method Download the idea is, given one string that represents the name of the file, we should capture him and return via the same method; already in the method Upload receive theStream matching the image and save it to disk and return the name that is randomly generated. Note: For space reasons, the implementation of the contract will not be displayed here, but is contained within the project example, related to the article. As shown and discussed above, you will have the Stream as the body of the message. But what if, at some point, want to spend any extra information? As the body is exclusively reserved for the contents of Stream , we can use the headers of the message to accommodate such information. Again, this will change the way we create the contract, requiring specify declaratively, the contract of the message, informing the headers and the body additional message that will remain the Stream . The code snippet illustrates how we should proceed to the creation of this contract:



using System;
using System.IO;
using System.ServiceModel;

[MessageContract]
public class StreamData
{
    [MessageHeader]
    public string FileName;

    [MessageBodyMember]
    public Stream Content;
}
In the above example, the attribute MessageContractAttribute defines a class that will match the SOAP message to be trafficked; has the attribute MessageHeaderAttribute specifies a member that will be part of the header of the message, and finally the attribute MessageBodyMemberAttribute determine the member that will be the message body. With this, the interface representing the service contract will also undergo changes: instead it deal directly with Streams , it receives and returns instances of the class StreamData . The code below shows aninterface very similar to that used above ( IImagens ), but now with this new technique:
using System;
using System.IO;
using System.ServiceModel;

[ServiceContract]
public interface IArquivos
{
    [OperationContract]
    StreamData Download ();

    [OperationContract]
    void Upload (StreamData data);
}

Note: Again, for space reasons, the implementation of the contract will not be displayed here, but is contained within the sample project related to the article. Regardless of the technique you use when creating the contract, an important detail and that needs to be discussed is in relation to the closing of the Stream that travels from one side to another. Who will be responsible for closing it? Usually the Stream will be sent both from client to server, and the server to the client. Who sends the Stream should not close it; the runtime WCF will. Already on the side of those who receive the Stream should close it after using it. A last detail: when we are operating with data that exceeds the default configuration for sending and receiving information, we need to pay attention to specify a value that can accommodate information will be exchanged. The bindings associated with this technique have two properties that directly affect Streamed , namely: MaxBufferSize and MaxReceivedMessageSize . Because these settings are not included within the contract (WSDL) of the service, then it becomes the responsibility of the developer to specify a value other than the default, if you want to accept more than the specified content. 's format Streamed addictive platform and consequently , is not interoperable as MTOM. Also, have restrictions on the level of contract is restricted for use by only three bindings and security can only be guaranteed by transport.Already as a positive point, we have a smaller memory consumption as well as better performance due to the nature of shipping. Thinking of these characteristics, it is likely that you already can know whether or not you choose to use it. Serialization is important to say that the serialization process is independent of the transfer (encoding ). Serialization is a process that defines how objects are mapped to XML Infoset , while the encodingdetermines how these XML Infoset be written (in bytes ) and sent to any of the encodings that we have seen above that, in turn, occurs at the level of transportation. Another important point is in relation to the contract.Regardless of the encoding chosen, it will not result in any change in the service contract, unlike the serialization process that, in turn, can influence the creation of it. As the serialization is an important process and a little extensive, it is not discussed in this article. Conclusion: As we noted throughout the article, WCF decouples the maximum possible implementation of execution, allowing the contract has no knowledge about the how the service is being exposed and consumed. But in some cases, we can change the default behavior is not limited to just change a setting but change the interface determines that the contract of service. It is important to carefully consider each of the encodings and transfer modes to see which one fits best in your solution.


Encodings
You should carefully evaluate which of these encodings choose. It is important to remember that if you need a combined these details, for example, support interoperability and good performance, you can expose differentendpoints , each of which is specific to each of these characteristics. these classes are contained within theSystem namespace. ServiceModel.Channels , inheriting from a base class called MessageEncodingBindingElement. The hierarchy of encodings is displayed through the image below:
The table below illustrates the encoding corresponding (standard) for each of the bindings within the existing NET Framework:
* Types contained within the Assembly System.ServiceModel.Web.dll which is available from the NET Framework 3.5.


  • Buffered: With this option, the message is fully loaded into memory before being sent to the recipient.This option is the default setting for all bindings within the existing .NET Framework.
  • Streamed: Already with the option Streamed , only the header of the message is loaded into memory (should not exceed the maximum amount specified in the property MaxBufferSize ), while the body is defined as a stream , allowing small pieces of content to be read at a time . This setting affects both the request as the answer.
  • StreamedRequest: Only apply the stream in a request, but the response will be placed in buffer . It is a good option only when we accept Stream as a parameter in operations one way .
  • StreamedResponse: Only apply the stream in a response, while the request is placed in buffer . This option is useful only when the output of the method returns a Stream .
To make such a configuration, we must resort to the use of the property TransferMode which, in turn, accepts one of four options contained in the enumerator TransferMode . This property is only exposed in bindings that support the technique of streaming , and they are: BasicHttpBinding , NetTcpBinding and NetNamedPipeBinding . The only reason these bindings bearing the streaming is that there is some functional rules that must be followed explicitly, eg, digital signatures are defined and computed on the message content, and with the option to stream enabled, the contents will not be fully available to perform the task of verifying the same. As the option Buffered is the default and does not need any change, there is nothing to talk about it except as WCF treats internally, as we have seen above. Besides functional constraints imposed by mode Streamed , there are still some rules that need follow to get exposed as a service stream , and these rules involve the change in how we design the service contract. The idea is that the methods that will compose the contract must receive or return an instance of the class Stream , contained within the namespace System.IO ; this will depend on whether the service will return some binary content to the client or if the client sends some binary content to the service. these cases (use classStream ) parameter or the return of a method (operation) correspond to the body of message. To exemplify the use of this technique in our services, we can create a contract ( interface ) that has two methods: Upload andDownload , which receives and returns an instance of the class Stream , respectively:



Comments

Popular posts from this blog

WCF - Throttling and Pooling

WCF - Managing Instances