|
|
To print: Select File and then Print from your browser's menu
-------------------------------------------------------------- This story was printed from ZDNet Australia. --------------------------------------------------------------
|
Controlling Web service messages in .NET By William Dawson, Builder.com December 30, 2002 URL: http://www.zdnet.com.au/news/communications/soa/Controlling-Web-service-messages-in-NET/0,130061791,120270876,00.htm
Writing Web services in Visual Studio .NET may be easy, but how do you tweak the WSDL and SOAP that .NET builds? Think bracketed decoration attributes. The .NET Framework makes the creation of a Web service almost embarrassingly simple, particularly when you’re developing in Visual Studio .NET. Just about all you need to conjure the Web service spirits in an otherwise normal looking .NET code file is that magical 11-character incantation: [WebMethod]. With the [WebMethod] attribute decorating a class method, and with the class referenced in an .asmx file, ASP.NET will generate a complete service description in WSDL and begin serving up clients right away. No SOAP header
You can put whatever public fields you’d like into the class. Using the authentication example, you might include UserID and Password fields, as shown in Listing A. You also need to create a public instance variable of this header class inside your main Web service class. You can name this instance variable any way you’d like; I called it auth in Listing A. Don’t include any instantiation code for the variable; ASP.NET will take care of that. Having created a class and instance variable that can be used as a SOAP header element, you now need to tell ASP.NET which of the Web service methods use the header. As Listing A shows, just use the [SoapHeader] attribute of the System.Web.Services.Protocols namespace to decorate those methods that you want to have the header in their SOAP messages. Note that the first property in the [SoapHeader] attribute is the name of the instance variable of the special header class, which I called auth in Listing A. The value given to the Direction property indicates that only requests (inbound messages) use this header, and the Required property mandates its use; a request message that doesn’t contain a required header will result in the server returning a SOAP fault. If you now build the service and visit its .asmx file to take a look at the sample SOAP, you’ll see that the request message contains the header element with two child elements, each representing one of the public fields of the special header class. Since you’ve told ASP.NET to expect the header, you can actually use that instance variable inside the code for your Web method. Listing A accomplishes this by passing the auth variable to another function to validate the user. ASP.NET instantiates the auth variable, so you do not see any instantiation code such as auth = new AuthenticationHeader() in Listing A. A class with overloaded methods
If I simply decorate both of them with the [WebMethod] attribute, ASP.NET will complain that two messages can’t share the same name. Having no desire to change the class method names just to make ASP.NET happy, I can instead add the MessageName property to the [WebMethod] attribute, as in Listing B. This specifies SOAP message names of GetEmployeeByID and GetEmployeeByName for the overloaded methods. Although the WSDL will still have two different operations named GetEmployeeInfo within its SOAP binding, the operations will now have different soapAction attributes and different input and output message names. Making the service efficient For the next few examples, imagine that your Web service enjoys extremely high traffic and you are therefore very concerned about efficiency. In reviewing the service offerings, you find that some of the Web methods really do not require a response envelope to the client. In other words, these could be “fire and forget” requests. This is not quite as scary as it may sound; the client won’t simply send the message out on the wire and then stop listening (okay, so it’s not really “fire and forget”). In fact, the server holds the HTTP connection open while it loads and parses the request message, but it immediately returns an HTTP 202 response indicating that it has begun working on the request. So the client can at least be comfortable in the knowledge that everything was received and that the server considers the request message to be intelligible and well-formed. The net effect is that the HTTP connection is freed up faster and the server will not have to expend processing power to create and send a response envelope. All of this magic can be accomplished by decorating a method that returns void with one of the following System.Web.Services.Protocols namespace attributes:
Choose between the two based on whether you use Remote Procedure Call (RPC) formatting for the message. The default for all messages, in the absence of one of these two attributes, is the “document” style of formatting. So if you haven’t been using RPC for all of your other Web methods in the class, you will probably want to remain consistent and choose [SoapDocumentMethod]. With efficiency in mind, you might also decide to work on shortening the request and response messages; every byte counts! As in the earlier example with the overloaded methods, let’s assume you like following your normal programming practices and don’t wish to develop a different style simply for Web services. So you name methods and parameters with the same verbosity as you would for any other class. This keeps the code looking the way you want for purposes of documentation and reflection. More description properties
This means you can manipulate events at different stages of a Web service lifetime, which can be important when looking for a particular solution. For example, you may find that there is no SOAP-related attribute class to accomplish something, but you can turn to the XML serialization attributes to see if you can reach your goal by manipulating at that level. As you peruse these namespaces, look out especially for classes whose names end in “Attribute”. Each bracketed attribute corresponds to one of these classes; this is the case not only for attributes related to Web services, but also for all decoration attributes. For example, the [WebMethod] decoration attribute is really the System.Web.Services.WebMethodAttribute class. The public properties that you see in the class documentation can also be put inside the parentheses of the matching decoration attribute. A touch of elegance
Copyright © 2009 CBS Interactive, a CBS Company. All Rights Reserved. |