|
SYS-CON.TV Webcasts
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Top Links You Must Click On
ASP.NET Strengthening Your Attachments:
Sending binary data to your Web services using WS-Attachements
By: Michael Ruminer
Nov. 11, 2003 12:00 AM
In the early days of .NET Web services, using a Web service to accept binary data required converting the data to something that could be represented in XML. Surely you remember those days - back before December 2002. With the release of Web Service Enhancements (WSE) 1.0, followed shortly by WSE 1.0 SP1 in March 2003, and now with WSE 2.0 on the horizon, we can at last quickly and easily send binary attachments via Web services by utilizing WSAttachments. The support of the proposed WSAttachments standard in WSE is of particular interest to any programmer who has ever used a Web service in a production environment. You quickly realize how much you rely on data that doesn't lend itself to some sort of XML serialization. You may want your Web service to accept a word processing document, an image, or any of a number of binary data types. In the past, you might have encoded this binary data as Base64 and sent it over the wire as XML, reconstituting the data on the other side. While the process works well, it is in many cases clunky, and it is not useful in all situations. The SOAP attachments may be binary data, other SOAP messages, or any other data type you wish to send. WS-Attachments, as defined in the WSE and as submitted as a draft Web services standard, relies on Direct Internet Message Encapsulation (DIME). DIME is used much like MIME (Multipurpose Internet Mail Extensions) to encapsulate a message, and in fact uses the MIMEtypes to indicate the type of attachment it carries. An important thing to remember is that DIME encapsulates (as the name suggests) the SOAP message and its attachments - not the other way around. For the purposes of this article, we'll look at the practical application of the WSE classes in order to send a SOAP message with an attachment to a Web service that in turn responds with a different attachment. The demonstration code builds a Web service named CodeWidgetServices with a Web method Image2Jpg that accepts a SOAP message with an image file attachment. The Web service converts the attached image file to a JPEG image and returns the converted file's name in the SOAP message and the new JPEG as an attachment. If you don't need cookbook examples of implementing WSAttachments in your own projects, the quick checklist accompanying this article will keep you headed in the right direction as you go off on your own. If you prefer to read the article and code samples, the checklist will let you know where we are headed and is useful for quick referral.
Building the DIME Web Service You'll also need to add a reference to Microsoft.Web.Services.dll to your Web service project. In addition, you will need to check the web.config file for the Web service, ensuring that it has the soapExtensionTypes elements (see Listing 1). Ensure that if you are manually adding the soapExtension Types elements that the type attribute has no breaks or extra spaces in it despite how it may appear in the listing. If you have line breaks in the attribute value when you run the service, the .asmx page will indicate an invalid type.
Add aliases for the namespaces
you will use; otherwise you will
need to provide fully qualified
names in the code. The following
are the namespaces you will need to
reference in order to support DIME.
Setting Up a Web Method A person looking at the classically defined Web method would have to investigate carefully to discover that attachments are being utilized. Not only is this currently acceptable - I have failed to find any reference from Microsoft on best practices to avoid this sort of ambiguity. Later in this article I will show you how to avoid this ambiguity by using a recommended way to indicate that attachments are handled by a Web method. What about the WSDL? Can we look at the WSDL to discover that the method uses DIME? Yes and no. Using WSE 1.0 SP1 the WSDL is not automatically modified to indicate DIME. There is a proposed WSDL Extension for SOAP in the DIME specification. Nevertheless, WSE 1.0 SP1 does not implement this. Oddly enough, the SOAP Toolkit 3.0 does. Thus, if you wish the WSDL to indicate that you are using DIME, you will need to modify the WSDL file manually. It's not required that you do this if you are using WSE on the client consuming the Web service, but if you plan to use the SOAP Toolkit 3.0 with the client it needs the DIME information in the WSDL. For the scope of this article, the WSDL is not modified. As a programmer I don't want to have to look at the WSDL to see if a Web method utilizes attachments, and as we have learned, there is no guarantee that doing so will tell you whether or not the method utilizes attachments. Furthermore, the SOAP message could have an indefinite number of attachments. You may want to build code to ensure the message sent only what was expected. Or you may wish to have code validate that the attachment is the proper data type, e.g., not an image when the method was expecting an XML document. The best way to indicate the type and number of attachments expected - and that the method uses DIME - is to create a custom attribute. Listing 3 shows the class definition for a custom attribute named DimeCompliant Attribute. Listing 4 is the complete Web method code for Image2Jpg utilizing the DimeCompliant attribute. You will notice in the Web method that I have not checked the message against those attributes (because it is outside the scope of this article), but by utilizing reflection, you could validate that the message meets the expected message format. If nothing else, the attribute is a strong flag to the programmer that this Web method uses attachments and what sort of attachment it expects. In the case of the sample code, it indicates it expects one attachment of type Bitmap (which is any of a number of image types under .NET, e.g., JPEG, BMP, GIF, etc.). I hope that in the future such attributes will be required for members to receive DIME information. It only makes sense that a strongly typed language such as C# should not allow a message to be sent that can't be validated systematically against an expected signature. What do you need to do to set up a Web method to handle SOAP attachments? In short, you aren't required do anything special to the method itself; you can simply check the SOAP message for attachments. However, I can recommend better practices that use custom attributes.
Building the Web Method In the sample code, once the sent image has been converted to a JPEG we are now ready to create a new DimeAttachment made up of that JPEG image for the response SOAP message. This is done simply by creating a new DimeAttachment instance indicating the attachment's MIME type, TypeFormatEnum, and the stream that represents the actual attachment data. new DimeAttachment("image/jpeg", TypeFormatEnum.MediaType, myJpgStream) After assigning the DimeAttachment a friendly IDvalue, the attachment is added to the ResponseContext.Attachments collection. The Web method returns the new filename or the error text if any of a number of conditions occurs to prevent the Web method from returning a JPEG file. A DIME message containing the SOAP message and attachment will be returned to the client.
Setting Up a Client In the sample, the Web reference is named CodeWidget. There is one very important change on the client side that must be made in order to send and receive SOAP attachments in conjunction with a Web service. When using VS.NET and adding a Web reference, a proxy class named Reference.cs is created for the Web service. This file can usually be found under Project Folder/Web References/web reference name/Reference.cs, and will contain a class that is a proxy for the Web service referenced. This class typically inherits from System.Web.Services.Protocols. SoapHttpClientProtocol. In order to utilize DIME, the class needs to be changed to inherit from Microsoft.Web.Services.WebServicesClientProtocol. Note: If you have installed WSE 1.0, Reference.cs likely already contains an additional class that inherits from WebServicesClientProtocol. This additional class will have a class name ending in "Wse". Use this class to create the Web service instance in your code. A very useful aspect of the architecture of Web services built with WSE is that a client can communicate with the Web service method designed for attachments - without DIME - and the service will not throw an exception. It will see the SOAP message with zero attachments because of how the ASP.NET filters work with DIME. By the time the actual Web method sees the message, it is simply a SOAP message like any other with zero or more attachments.
Coding the Client
Using WSE 2.0
Conclusion
References Reader Feedback: Page 1 of 1
Enterprise Open Source Magazine Latest Stories . . .
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||