Transmitting Data by Using MTOM


A SOAP message usually contains a message body, which is held in an XML format. This body contains the data for a request being transmitted to a service or the information being returned in response to a request back to a client application. The actual structure of the information in the message body is specified by the WSDL description of the operation, which is in turn derived from the operation contract you specify in your services. For example, the ProductsService service that you created in Chapter 1, “Introducing Windows Communication Foundation,” defined the ChangeStockLevel operation in the IProductsService service contract like this:

 [ServiceContract] public interface IProductsService {     …     [OperationContract]     bool ChangeStockLevel(string productNumber, int newStockLevel, string                           shelf, int bin); }

When a client application invokes the ChangeStockLevel operation, the WCF runtime constructs a message that looks like this:

 <s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"  xmlns:s="http://www.w3.org/2003/ 05/soap-envelope">     <s:Header>         …     </s:Header>     <s:Body>         <ChangeStockLevel xmlns="http://tempuri.org/">             <productNumber>WB-H098</productNumber>             <newStockLevel>25000</newStockLevel>             <shelf>N/A</shelf>             <bin>40101</bin>         </ChangeStockLevel>     </s:Body> </s:Envelope>

You can see that the message body contains the parameters for the operation, encoded as an XML infoset. This scheme works well for parameters that have easily definable representations. However, remember that the XML message is transmitted as a series of text characters when it traverses the network, and non-text data, such as the <newStockLevel> and the <bin> elements in the example above, is being converted to and from a text representation as it is sent and received. This conversion incurs an overhead at two levels:

  1. It takes time, memory, and computational power to convert from the binary representation of an integer (in the case of the <newStockLevel> and the <bin> elements) to text and back again.

  2. The text representation of the data as it crosses the network might be less compact than the original binary representation; the bigger the number, the longer the text representation.

In this example, this overhead is minimal. However, how would you handle lengthy binary data, such as an image? One possible solution is to convert the binary data into a text representation containing the corresponding series of “0” and “1” characters. But consider the overhead of this approach. Converting a megabyte of binary data into a string a million characters long requires a significant amount of memory and time. What actually happens in this case is that WCF converts the binary data into a Base64 encoded string rather than a string of “0” and “1” characters. The result is a more compact text representation of the data. However, on average, the Base64 encoding mechanism results in a string that is approximately 140% of the length of the original data. Additionally, this data has to be converted back into its original binary format by the recipient of the data. Clearly, it makes sense to find an alternative representation when transmitting messages that include large amounts of binary data.

MTOM is a specification that provides just such a facility. When you use MTOM to transmit a message that includes binary data, the binary data is not encoded as text but is transmitted unchanged as an attachment to the message following the format of the Multipurpose Internet Mail Extension (MIME) specification. Any text information in the original message is encoded as an XML infoset as before, but binary information is represented as a reference to the MIME attachment, as depicted in Figure 12-1:

image from book
Figure 12-1: Encoding a message containing binary data.

Note 

MTOM supersedes previous proposed standards that you might have heard of, such as the Direct Internet Message Encapsulation protocol (DIME) and the WS-Attachments specification. Don’t confuse DIME with MIME.

As always, security is an important consideration. When signing MTOM messages, WCF computes a signature that includes the data in any MIME attachments. If any part of the message, including the MIME attachments, is changed between sending and receiving the message, the signature will be invalid. For more details about signing messages, refer back to Chapter 4, “Protecting an Enterprise WCF Service.”

In WCF, MTOM is handled by a specific encoding channel. If you are using any of the standard HTTP bindings (basicHttpBinding, wsDualHttpBinding, wsFederationHttpBinding, or wsHttpBinding), you can change the MessageEncoding property of the binding configuration to MTOM to use the MTOM encoding channel. Other transports, such as TCP, MSMQ, and Named Pipes, use their own proprietary binary encodings by default. The corresponding standard bindings do not have a MessageEncoding property, so if, for example, you want to use MTOM over TCP, you must create your own custom binding.

Sending Large Binary Data Objects to a Client Application

Consider this scenario: Adventure-Works wants, to extend the functionality available in the ShoppingCartService WCF service to enable a user to be able to view photographs of the products supplied by Adventure-Works. The database contains images of the products held as binary data. The developers have built a prototype service called ShoppingCartPhotoService that provides an operation called GetPhoto. This operation retrieves the image data from the database and returns it to the client application. In the following exercise, you will see how to encode binary data using MTOM over HTTP when transmitting the photographic data from the service back to the client application.

Use MTOM to transmit photographic images from the ShoppingCartService service

  1. Using Visual Studio 2005, open the solution file image from book MTOMService.sln located in the Microsoft Press\WCF Step By Step\Chapter 12\MTOM folder under your \My Documents folder.

    This solution contains a prototype WCF service called ShoppingCartPhotoService that implements the proposed GetPhoto operation. The ShoppingCartPhotoService service is hosted by using the ASP.NET Development Web Server provided with Visual Studio 2005. The solution also contains a basic WPF client application that displays data in a WPF form.

  2. Open the image from book ShoppingCartPhotoService.cs file in the App_Code folder in the C:\\MTOM-Service\ project.

    Examine the IShoppingCartPhotoService interface defining the service contract. This interface contains the GetPhoto operation. This operation enables a client application to request the photograph of a product given its name. The photograph itself is passed back to the client application in the photo parameter, which is marked as out. The type of this parameter is byte[], because the photographic images are held as raw binary data in the database. The return value is a Boolean indicating whether the operation was successful or not.

    If you have time, look at the implementation of the GetPhoto method in the ShoppingCartPhotoServiceImpl class. There is nothing specific to WCF in this method; all it does is query the Production.ProductPhoto table in the database to find the photograph for the specified product (for clarity, this method does not perform any checks to deter SQL Injection attacks). The photograph is held as a varbinary column of unspecified length in the database, so the code reads the contents of this column in manageable chunks and then pieces these chunks together to construct the byte array that is passed back to the client application.

    Note 

    The size of the chunks used by this method is specified by the chunkSize integer constant. The developer can increase or decrease the value of this constant to determine the optimal chunk size.

  3. Open the image from book Window1.xaml file in the ShoppingCartGUIClient application. This XAML file defines a WPF form that contains an image control occupying the main part of the form, together with a label, a text box, and a button. The user types a product number into the text box and clicks the “Get Photo” button.

  4. Open the image from book Window1.xaml.cs code file behind this form (expand the image from book Window1.xaml node in Solution Explorer to display the file). The onGetPhotoClick method in this file runs when the user clicks the “Get Photo” button. The code in this method creates an instance of the client proxy, reads the product number typed in by the user, creates a new byte array, and then invokes the GetPhoto operation passing in the byte array and the product number as parameters. If the operation returns true, the method uses the byte array containing the data for the photograph and uses it to populate a BitmapImage object, which it then displays in the image control on the WPF form.

  5. Start the solution without debugging. The ShoppingCartPhotoService starts the ASP.NET Development Web Server and starts listening on port 9080.

    When the ShoppingCartGUIClient form appears, type WB-H098 in the product number text box and then click Get Photo. An image showing a pair of water bottles appears in the image control on the form, like this:

    image from book

    Type PU-M044 in the product number text box and then click Get Photo. This time the image displays a picture of a mountain pump.

  6. Close the client form and return to Visual Studio 2005.

  7. In Solution Explorer, edit the image from book Web.config file in the C:\\MTOMService\ project by using the WCF Service Configuration Editor.

  8. In the left pane, right-click the Diagnostics folder. In the right pane, click the Enable MessageLogging link.

  9. In the left pane, expand the Diagnostics folder and click the Message Logging node. In the right pane, set the LogEntireMessage property to True.

  10. In the left pane, expand the Sources folder under Diagnostics and then click the System.ServiceModelMessageLogging node. In the right pane, set the Trace level to Verbose.

  11. Click the Diagnostics node again in the left pane. In the right pane, click the Enable Tracing link. In the left pane, click System.ServiceModel in the Sources folder, and in the right pane, set the Trace level to Verbose.

  12. Save the configuration file, but leave the WCF Service Configuration Editor open.

  13. In Visual Studio 2005, start the solution again without debugging. Using the ShoppingCartGUIClient form, retrieve and display the photographs for products WB-H098 and PU-M044 and then close the ShoppingCartGUIClient form. Stop the ASP.NET Web Development Server by right-clicking the ASP.NET Development Server icon in the Windows taskbar and then clicking Stop.

  14. Start the Service Trace Viewer in the Tools program group in the Microsoft Windows SDK program group. In the Service Trace Viewer, open the file web_messages.svclog in the Microsoft Press\WCF Step By Step\Chapter 12\MTOM\MTOMService folder under your \My Documents folder.

  15. In the left pane, click the Message tab. Four messages are listed; one for each request and response. Click the first message. In the lower right pane, click the Message tab and scroll down to display the body of the message. You should see that this is the message requesting the photograph for product WB-H098.

  16. In the left pane, click the second message. In the lower right pane, examine the message body. This is the response containing the photographic data in the <photo> element. You can see that this data consists of a long string of characters containing the Base64 encoding of the binary data. Examine the remaining messages; the third message is the request for the photograph of product PU-M044, and the fourth is the response containing the Base64 encoded image data.

  17. Open the web_tracelog.svclog file, and then click the Activity tab in the left pane. This file contains a log of the work performed by the WCF runtime, and the Activity pane displays a list of all the tasks the WCF runtime on the service performed.

  18. Locate and click the first item named “Process action ‘http://adventure-works.com/2007/03/01/ShoppingCartService/GetPhoto.’” The upper right pane displays the tasks performed by this activity, including receiving the message over the channel, opening an instance of the service, executing the operation, creating a response message, sending the response message, and finally, closing the service instance.

  19. In the upper right pane, scroll down and click the task “A message was written.” The lower right pane displays information about the message. In the Message Properties and Headers section, note that the Encoder property is “application/soap+xml; charset=utf-8.” This indicates that the message was encoded as text:

    image from book

  20. On the File menu click Close All, but leave the Service Trace Viewer running.

  21. Return to the WCF Service Configuration Editor editing the image from book Web.config file for the ShoppingCartPhotoService service. In the left pane, click the ShoppingCartPhotoServiceBindingConfig binding configuration in the Bindings folder. This is the binding configuration used by the HTTP endpoint. In the right pane, change the MessageEncoding property from Text to MTOM. Save the configuration file and then close the WCF Service Configuration Editor.

  22. In Visual Studio 2005, edit the image from book app.config file in the ShoppingCartGUIClient project using the WCF Service Configuration Editor. In the left pane, click the WSHttpBinding_ShoppingCartPhotoService binding configuration in the Bindings folder. In the right pane, change the MessageEncoding property to MTOM. Save the configuration file and then close the WCF Service Configuration Editor.

  23. Using Windows Explorer, delete the files web_messages.svclog and web_tracelog.svc in the Microsoft Press\WCF Step By Step\Chapter 12\MTOM\MTOMService folder under your \My Documents folder.

  24. In Visual Studio 2005, start the solution without debugging. Fetch and display the photographs for products WB-H098 and PU-M044. Close the ShoppingCartGUIClient form, and then stop the ASP.NET Web Development Server.

  25. In the WCF Service Trace Viewer, open the web_tracelog.svclog file. In the Activity pane, locate and click the first item named “Process action ‘http://adventure-works.com/2007/03/01/ShoppingCartService/GetPhoto.’” In the upper right pane, locate and click the task “A message was written.” In the lower right pane, examine the Encoder property in the Message Properties and Headers section. This time the Encoder property is set to “multipart/related; type=’application/xop+xml.’” This indicates that the service sent a MIME multipart message:

    image from book

  26. Close the WCF Service Trace Viewer.

    Note 

    If you examine the SOAP messages in the web_messages.svclog file, you might be surprised, and possibly disappointed, to see that the <photo> parameter returned in the GetPhotoResponse message always appears to be encoded as a Base64 string embedded in the message. Do not be fooled. MTOM is actually transparent to WCF SOAP message logging in much the same way that it is transparent to your own applications, and so it is not aware that the <photo> parameter is being transmitted as an attachment. If you really want to see the SOAP message in its raw format with the attachment, you must use a network analyzer, such as Windows Netmon.

You have seen that configuring a binding to use the MTOM encoding is a very straightforward task. Using MTOM does not affect the functionality of your applications, and you don’t have to make any special coding changes to use it.




Microsoft Windows Communication Foundation Step by Step
Microsoft Windows Communication Foundation Step by Step (Step By Step Developer Series)
ISBN: 0735623368
EAN: 2147483647
Year: 2007
Pages: 105
Authors: John Sharp

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net