the Web service name, normally taken from the class name. The name is typically used when generating proxy classes from the WSDL document of the Web service.
We will not be using these properties in our TempConverter class declaration, although we will use the Namespace property later in Chapter 26 when we cover Web service deployment and publishing.
Creating Web methods
Now that we have the skeleton of our CTemp Web service in place, we are ready to add the method declaration that will provide the implementation for our Web service.
So far, we have turned a normal class definition into a Web service simply by adding the Web service declaration to the ASMX file. This same model is used to identify a Web method. Specifically, a normal method declaration becomes a Web method by adding the WebMethod attribute to it.
The TempConverter class contains the following Web method declaration.
VB.NET:
<WebMethod()> Public Function CTemp(ByVal Temperature
As Decimal, ByVal FromUnits As String, ByVal ToUnits As String) As Decimal
...
End Function
C#:
[WebMethod]
public Decimal CTemp(Decimal Temperature, String FromUnits,
String ToUnits) {
...
}
Let's examine this declaration for a moment. The first thing that you should notice (and also appreciate) is that the method declaration looks quite similar to function or method declarations you are already used to writing in previous versions of Visual Basic.
But, perhaps more important than what is the same is the recognition of what is missing from this declaration. Note that no reference exists to SOAP, XML, HTTP, or any of the other technologies that are required for Web services. All of these details are buried in
the plumbing provided by the ASP.NET runtime and the .NET Framework. All we have to do is mark our methods with the WebMethod attribute, and the .NET Framework takes care of the rest.
You should notice that the WebMethod syntax is similar but slightly different depending on the language in use. This reflects the personality of the language syntax itself, making the particular method of declaring the WebMethod a more natural extension of the specific language being employed.
The only part of our method declaration that is remotely different from traditional component programming in Visual Basic is the introduction of the <WebMethod()> attribute. The simple addition of this attribute to a public method declaration instructs Visual Basic or C# to make this method a Web method. This results in additional support for serialization/deserialization of XML, the mapping of all data types to XML, and the formatting/exchange of SOAP-based messages.
Note The WebMethod attribute can also be applied to public properties of a class, making these Web-callable as well.
Notice that the WebMethod() attribute also has room (within the parentheses) for attribute properties. Attribute properties enable you to override default behavior or enable Web methods with additional functionality.
Table 25-5lists the properties that you can add to the WebMethod attribute.
Table 25-5: WebMethod attribute properties
Property Name
Description
EnableSession
MessageName
Description
Provides a brief description of the functionality of the Web method.
Enables session state so that state can be maintained between method calls.
Used to provide an alias name for Web methods. This is typically required when implementin g polymorphic methods in a class.
TransactionOption
Allows the
Web
method to
support
transactions
(similar to
Table 25-5: WebMethod attribute properties
Property Name
CacheDuration
BufferResponse
Description
the transaction support provided by MTS and COM+).
Enables output caching so that the results of a particular method call can be saved to a cache and reused, rather than regenerated
.
Permits the server to buffer the response and transmit it only after the response has been completely generated.
We won't use these optional properties in our CTemp Web service method, however, these properties are covered in Chapter 23, "Web Services Infrastruture." You can also learn more about these properties by referring to the .NET Framework online documentation.
Adding the implementation code
After you have added the Web method declaration, you are ready to insert the code that actually performs the temperature conversions. Enter the following code into the CTemp.asmx file within the CTemp Web method.
VB.NET:
Select Case FromUnits.ToUpper.Chars(0)
Case "F" 'Fahrenheit
Select Case ToUnits.ToUpper.Chars(0)
Case "F" 'No conversion necessary
Return Temperature
Case "C" 'Convert Fahrenheit to Celsius
Return ((Temperature - 32) * 5) / 9
Case "K" 'Convert Fahrenheit to Kelvin
Return (((Temperature - 32) * 5) / 9) + 273.15
Case "R" 'Convert Fahrenheit to Rankine
Return Temperature + 459.67
Case Else
'Throw exception
Throw New ArgumentException("Bad ToUnits arg.") End Select
Case "C" 'Celsius
Select Case ToUnits.ToUpper.Chars(0)
Case "C" 'No conversion necessary
Return Temperature
Case "F" 'Convert Celsius to Fahrenheit
Return ((Temperature * 9) / 5) + 32
Case "K" 'Convert Celsius to Kelvin
Return Temperature + 273.15
Case "R" 'Convert Celsius to Rankine
Return (((Temperature * 9) / 5) + 32) + 459.67
Case Else
'Throw exception
Throw New ArgumentException("Bad ToUnits arg.") End Select
Case Else
'Throw exception
Throw New ArgumentException("Bad FromUnits arg.") End Select
C#:
switch (FromUnits.ToUpper().Substring(0,1))
{
case "F": //Fahrenheit
switch (ToUnits.ToUpper().Substring(0,1))
{
case "F": //No conversion necessary return Temperature;
case "C": //Convert Fahrenheit to Celsius return ((Temperature - 32) * 5) / 9;
case "K": //Convert Fahrenheit to Kelvin
return (((Temperature - 32) * 5) / 9) + (Decimal)273.15; case "R": //Convert Fahrenheit to Rankine
throw new ArgumentException("Bad FromUnits arg.");
}
As noted earlier, the logic of our CTemp Web service does not change, regardless of whether or not the method is marked as a WebMethod.
Handling errors
The .NET Framework, via the CLR, provides excellent support for handling errors via exceptions. Applications built on the .NET Framework can throw and catch exceptions to handle all types of run-time errors. This support is also available to Web services.
Generally, you will want to use exceptions to communicate run-time errors back to Web service consumers for conditions that your service cannot handle effectively. As you can see in our implementation of the CTemp Web method, there are several cases in which we must throw exceptions based on invalid input obtained from the consumer in the method call.
Web services communicate exceptions to consumers via SOAP exception messages. A SOAP exception is represented by the SoapException class in the .NET Framework's System.Web.Services.Protocols namespace. As a Web service consumer, you can wrap calls to Web service methods within try . . . catch blocks to intercept exceptions thrown by Web services.
Referring to our CTemp implementation, arguments that cannot be processed as specified by the consumer cause the Web service to throw an ArgumentException exception. This exception is serialized into a SOAPException message and returned to the consumer.
Note that communicating exceptions to Web service consumers is only supported via SOAP. Therefore, if you use HTTP -GET or HTTP -POST to call a Web service method (as is the case when using a Web browser to test and invoke Web services), you cannot get exceptions transported back to the browser. In this case, the exception within the Web service is handled by the Web server, which results in the transmission of a server error page back to the consumer.
Building the Web service
Now that we've added all the implementation code to our CTemp Web service, we are ready to build it. For inline Web services (such as our CTemp Web service, where the implementation code is contained in the ASMX file), a separate build of the code is not necessary, because the ASP.NET runtime recognizes when it is necessary to compile and build the Web service automatically.
If your Web service is being invoked for the first time, ASP.NET will build the Web service and cache the application code for future reference. Each subsequent request for your Web service will then be handled by the cached executable. If the ASP.NET runtime is restarted, however, the cache is lost and the next request for your Web service will result in the build and cache process being repeated.
The automatic build capability of ASP.NET is yet another example of how ASP.NET and the .NET Framework make it easy to build Web services. In the simplest case, you can copy your Web service ASMX file to a target Web server as is. ASP.NET will take care of the rest.
Having a complete Web service in place on your Web server, you are now ready to test it. We will cover Web service testing in the next section.
Testing the Web Service
The .NET Framework provides a quick and simple method you can use to test your Web service. Specifically, you can test your Web service using a Web browser and the HTTP - GET protocol. This technique does not require developing a consumer application.
Note This technique works only for the HTTP-GET protocol support that is provided by the browser. By default, an ASP.NET Web service supports the HTTP-GET, HTTP-POST, and HTTP-SOAP protocols.
In addition to using a Web browser with HTTP -GET, you can test your Web service using a Web browser with HTTP-POST, with a slight modification to the default ASP.NET page used to view Web services. Finally, you can test your Web service by developing a custom consumer application. We will discuss this technique in Chapter 28, "Consuming Web Services," where we will build a consumer to invoke the CTemp Web service.
The following sections describe how to use your Web browser with the HTTP-GET and HTTP-POST protocols to test your Web service.
Testing with HTTP-GET
Using a Web browser to test your Web service with the HTTP-GET protocol does not require you to develop a consumer application. Therefore, this is a quick and easy way to perform some initial testing of your Web service.
The HTTP-GET protocol encodes data (in this case, method arguments) as query string parameters when posting to the server. This encoding method is used to pass the proper method input arguments as query string arguments.
Two ways exist to invoke the HTTP -GET protocol using a Web browser to test your Web service. You can use the built-in test page offered by the ASP.NET runtime or you can encode the complete URL to your Web service using location, method name, and any input arguments as query string parameters in the Address bar of your browser. We will illustrate each of these techniques using our CTemp Web service as an example.
Using the Web service test page
The ASP.NET runtime provides excellent support for interactive viewing of Web service information and capabilities, as well as basic HTML forms for performing interactive tests using the HTTP-GET protocol support built into your browser.
ASP.NET provides this capability via a Web service help file template named DefaultWsdlHelpGenerator.aspx. By default, this file is located in the \Winnt\ Microsoft.NET\Framework\version\CONFIG folder. Note that this is just an ordinary ASP.NET page, so you can customize this page to suit your particular needs. What's more, you can copy this file to your Web service virtual application folder to provide custom capabilities for each Web service application that you create. We will cover how to do this shortly.
Using the Web service help template to view Web service information is as simple as entering the URL to your Web service entry point file (the ASMX file) into the Address bar of your browser.
To view the help page for our CTemp Web service, type the following URL in your Web browser Address bar (this example assumes that the Web service is available on your local machine):
http://localhost/ctemp/ctemp.asmx
This will cause the Web server to execute the help file template and return a page similar to Figure 25-7.
Figure 25-7:Web service help page
This page shows us the name of the Web service (TempConverter), the methods that it supports (in this case, the single method named CTemp), and a link to the Web service WSDL document.
The second part of this page includes a warning regarding the use of the temporary namespace URI http://tempuri.org/ for our service. This namespace is used to uniquely identify your Web service from all others, and should be changed before deploying your Web service for public consumption. During initial development, however, it is not necessary to change this URI. We will discuss the Web service namespace URI and how to change it in Chapter 26, "Deploying and Publishing Web Services."
Let's continue our exploration of the Web service help page by following some of the links found on the page. We will begin by taking a look at the WSDL service contract.
Viewing the WSDL service contract
Let's take a quick look at the WSDL service contract document for the CTemp Web service. To view the WSDL service contract, simply click the Service Description hot link
on the Web service help page. This will display the WSDL XML file contents, as shown in Figure 25-8.
Figure 25-8:WSDL document in Web browser
Note the URL in the Address bar of the browser window. The base URL is the same (it points at our ASMX file), but the URL now also includes the following query string:
http://jdc7200cte/CTemp/CTemp.asmx?WSDL
This query string instructs the ASP.NET to generate and display the WSDL service contract for the specified Web service.
You may be wondering at this point how this process works, because no actual WSDL file is stored in the virtual directory of your Web service application. The .NET Framework supports a feature called reflection, which basically means that a .NET class can be queried to obtain information about the properties, methods, events, and other features it offers via its programmatic interfaces.
This is a great feature, because you don't have to worry about keeping a separate WSDL file in sync with the actual class that implements the capabilities of the Web service. Simply let ASP.NET use run-time reflection to query the Web service class and dynamically generate the WSDL contract all at once.
Now that you have had a chance to look at the WSDL service contract for your Web service, let's take a look at the help page provided for the CTemp Web method.
Viewing Web method help
If you followed the instructions in the last section to view the WSDL service contract, click the Back button in the browser window to return to the main Web service help page. Now, click the CTemp method hot link. This displays in your browser a page similar to Figure 25-9.
Figure 25-9:Web method help page
Note the URL that appears in the Address bar of the browser window. The base URL is again the same as before (it points at our ASMX file), but the URL now includes a new query string, as follows:
http://jdc7200cte/CTemp/CTemp.asmx?op=CTemp
This query string instructs the IIS Web server (or, more specifically, the ASP.NET runtime) to display a page that contains detailed information about the Web service method specified as the value part of the query string argument (in this case, the CTemp method).
The first part of the Web method help page contains a hot link that will return you to the main Web service documentation page. Underneath this link is a simple form that permits you to invoke the Web service method.
The second part of the Web method documentation page contains sample SOAP, HTTPGET, and HTTP-POST request and response message definitions. These are the messages that will be exchanged between the Web service and the consumer for this method call for the three supported message transports.
On this page, we have the ability to test our CTemp method by interacting with a form in our browser. Using this form, we can enter test values for the input arguments and click the Invoke button to execute the CTemp method using the HTTP-GET protocol.
Let's go ahead and test our service with some sample input. Enter the following information into the test form and click the Invoke button when you are finished:
§Temperature: 78
§FromUnits: F
§ToUnits: C
The form data is posted to the Web server using the HTTP-GET protocol. The Web server receives the URL and passes it to the ASP.NET runtime, which locates your Web service, creates an instance of the implementation class, calls the target method with the specified input arguments extracted from the query string parameter list, and returns the serialized XML result to your browser window, as shown in Figure 25-10.
Figure 25-10:XML results returned from method execution
The XML lists the return type in the element name and displays the return value of 25.5 within this element. Note the URL that is displayed in the browser Address bar. This URL shows how the query strings are formatted to specify the input arguments required by the method that appears as the last component of the base URL.
Manually invoking a Web service method
In addition to using the Web service test page to test our CTemp method using the HTTP-GET protocol, we can manually enter a properly formatted URL into the Address bar of our browser, which encodes the method name and input arguments as query string parameters, as follows:
Entering this URL into your browser will result in the same XML-encoded response from the Web server as that which we obtained when testing the Web service using the test form generated by the DefaultWsdlHelpGenerator.aspx page described in the last section.
Testing with HTTP-POST
Just like the HTTP-GET protocol, we can use a Web browser to test our Web service with the HTTP-POST protocol without going to the trouble of writing a consumer application.
The HTTP-POST protocol encodes data as name/value pairs within the body of the HTTP request when posting to the server, rather than encoding data in the form of query strings, as does HTTP-GET.
With only a few minor modifications to the default Web service help page and our application configuration file, we can test our CTemp Web service using the HTTP -POST protocol. To do this, follow these steps:
1.Copy Winnt\Microsoft.NET\Framework\version\CONFIG\ DefaultWsdlHelpGenerator.aspx to the CTemp Web service virtual directory.
2.Rename the file "CTemp.aspx."
3.Edit CTemp.aspx with your favorite text editor.
4.Change the showPost flag to True.
5.Save the changes to the file.
6.Create a text file named "Web.config" in the CTemp virtual directory with your favorite text editor (if you do not already have a Web.config file).
7.Add the following text to the Web.config file:
8.<?xml version="1.0" encoding="utf-8" ?>
9.<configuration>
10.<system.web>
11.<webServices>
12.<wsdlHelpGenerator href="CTemp.aspx" />
13.</webServices>
14.</system.web>
</configuration>
15. Save the changes to the file.
You can now test your CTemp method using the HTTP-POST protocol. To do this, enter the URL to the CTemp entry point file into your browser's Address bar as follows: