Web Services Applications: System.Web.Services

< BACK  NEXT >
[oR]

The fundamental concepts of Web services SOAP, WSDL, and the rest were described in Chapter 2. The chapters since then have described the suite of technologies provided by the .NET Framework. ASP.NET's support for Web services combines these two things, providing a way to build .NET Framework applications that expose and use SOAP-callable methods.

Web Services Servers

Like the browser applications described so far, the server side of an ASP.NET Web services application relies on pages. As shown in Figure 7-6, the files containing those pages have an .asmx extension rather than .aspx, and they don't contain any HTML. Apart from an occasional directive, they're just code. No HTML is required because a Web service is accessed by software, not by people, so it doesn't display a user interface. Ultimately, of course, there is often some human being whose request triggered the Web service, but the interface that person uses to accomplish this is outside the scope of the Web service itself. Web services don't define GUIs; .asmx pages don't contain HTML. As the figure also indicates, Web services applications are nothing more than managed objects, so they can use ADO.NET for data access and other available services.

Figure 7-6. A Web services application is built using .asmx pages, which produce managed objects when they're accessed.
graphics/07fig06.gif

Web services applications rely on .asmx pages

The WebMethod attribute is used to expose a method as a Web service

To expose a method contained in an .asmx file as a Web service, all that's required is to insert the attribute WebMethod in front of the method declaration. That's it. When the file is compiled, this attribute will be stored in the metadata of the resulting assembly, like all attributes. Its presence signals to the ASP.NET infrastructure that this method should be made accessible as a Web service. To give you a sense of how simple this is to do, think back to the Compute class used in Chapter 4's language examples. An .asmx file that exposed the C# version of that class's two methods as Web services might look like this:

 <%@ WebService Language="c#"  %> using System.Web.Services; public class Compute {     [WebMethod]     public int Factorial(int f)     {        int i;        int result = 1;        for (i=2; i<=f; i++)           result = result * i;        return result;     }     [WebMethod]     public double SquareRoot(double s)     {        return System.Math.Sqrt(s);     } } 

The file's contents begin with a WebService directive. Similar in form to the Page directive shown earlier, this line indicates that the Web service specified in this .asmx page is written in C# and defines a class named Compute. Next appears a using statement for the namespace System.Web.Services, followed by the definition of the Compute class. This class is virtually identical to what was shown in Chapter 4. For simplicity, this version doesn't use an interface, although that's not an important distinction here. What is important is the presence of the WebMethod attribute before each of the class's methods. This attribute is defined in System.Web.Services, hence the using statement that precedes this class, and it's the only addition required to expose these methods as Web services. Note, however, that only public methods can be marked with the WebMethod attribute.

Web services applications are deployed as ASP.NET applications, just like applications built using .aspx pages. As with .aspx pages, an .asmx page is compiled when it is first accessed by a client. The resulting assembly is stored on disk and then reused until the .asmx page that produced it is modified. Changing this page results in an automatic recompile the next time the page is accessed.

Web services applications are ASP.NET applications, too

When an .asmx page is accessed through a browser, ASP.NET uses reflection to learn what Web services it exposes. ASP.NET uses this knowledge to create a Web page that allows learning about these services. The Web page provides a way to invoke the services, examples of what calls to these services look like on the wire, and even a full WSDL definition of the Web services defined in this .asmx page. In reality, of course, the clients for Web services will usually be software other than a browser, but it's still nice to have this Web page generated for you as it provides an easy way to verify that your methods are available.

ASP.NET allows accessing an .asmx page from a browser

Like browser-focused ASP.NET applications, ASP.NET applications that provide Web services can also use a code-behind option. In this case, the .asmx file contains just the WebService directive with a reference to the assembly that contains the class. The actual code for that class is in a separate file, just as with browser-accessible ASP.NET applications.

Web services applications can use the code-behind option

Web Services Clients

Servers are useless without clients. To create a client capable of invoking the Web services in some server, a developer must first create a proxy class that exposes the same methods. This proxy can be created in Visual Studio.NET just by adding a Web reference to a project or by specifying an .asmx file, a WSDL file, or something else. Given this information, Visual Studio.NET will extract the information it needs to build a proxy for the desired Web service. It's also possible to create a proxy manually using wsdl.exe, a command-line tool that reads in a WSDL file and produces a proxy in the desired programming language. Once this proxy exists, the client can create an instance of that class and call its methods just like any other class. The proxy will forward each call to the destination Web service, that method will execute, and any results will be returned though the proxy.

Web services clients depend on proxies

This is much like .NET Remoting, where a proxy object communicates through channel objects to interact with an object in another app domain. With Web services, however, the remote object might well be written in Java and running on Linux. ASP.NET's SOAP implementation is distinct from the one provided by .NET Remoting, even though the concepts and terminology are similar.

It's also possible to invoke a Web service asynchronously. Rather than make the call and then block waiting for a response, a client can call the Web service and go about its business. When it gets the chance, the client can check to see what results, if any, the call has returned. To do this, the client uses two methods provided by the proxy along with the normal synchronous method for each Web service it supports. The first of these begins the call, passing in any parameters, and then returns control to the client. The second ends the call, returning any results that have come back. Other options are also possible, allowing the client to avoid repeatedly checking for the call to be completed.

Web services can be called asynchronously

Options for Web Services Applications

Building straightforward Web services such as those just shown could hardly be simpler. Adding one attribute isn't much work, and building a client proxy is also dead easy. But then, the methods in this example's Compute class don't do much either. Web services methods that do real work commonly require a bit more complexity than what's been shown so far. This section describes some of the options ASP.NET provides for creating more powerful and more useful Web services.

For example, what if a Web services application needs to maintain state about its client between requests? Just as with the .aspx pages of a browser application, object instances defined via an .asmx page are created, used, and then destroyed for each request. Without some outside help, a Web services application can't store any in-memory information between requests. Fortunately, this outside help is available in the form of the standard objects provided by ASP.NET for this purpose. If a class that includes Web services methods inherits from System.Web.Ser-vices.WebService, code in that class can access the Session object, the Application object, and others. Through these, a Web services application can maintain state about its clients, access the User object to learn who the client is, and use the other services provided by these objects.

Web services applications can use built-in objects to manage their state

Why Are There Two Separate SOAP Implementations in the .NET Framework?

As described in Chapter 5, .NET Remoting includes an implementation of SOAP. ASP.NET includes another implementation of SOAP. On the face of it, this makes no sense. Why include two completely separate implementations of the same technology in the .NET Framework class library?

The short answer is: different groups, different goals. Recall that the goal of .NET Remoting is to communicate effectively across a network when both client and server are running the .NET Framework. SOAP is used primarily because, when mapped to HTTP, it allows this communication to pass through firewalls. In ASP.NET, on the other hand, the goal is to interoperate with any other implementation of SOAP, not just with the .NET Framework. SOAP is used both because it can pass through firewalls and because it's supported by many vendors.

A primary result of these different goals was described in Chapter 5: how serialized CLR types are mapped into XML. .NET Remoting uses the SOAP formatter, which allows everything that can be expressed by a CLR-based application to be passed across the network, including private data members and more. ASP.NET's SOAP implementation is not so committed to full-fidelity transfer of CLR types. Instead, it strives to produce a purely standard XML representation in everything it transmits, so it uses the XmlSerializer class to serialize and deserialize information. Sending a serialized type across ASP.NET's SOAP implementation won't send any private data members, for example, since XML has no notion of private members. The XmlSerializer emphasizes faithfulness to XML's XSD type system, while the SOAP formatter used in .NET Remoting emphasizes faithfulness to the CLR types.

Where .NET Remoting targets the homogeneous case, ASP.NET's Web services are optimized for heterogeneity. In a perfect world, the imperfections that drive this division wouldn't exist. Given the complexities engendered by different type systems, different vendors, and the still-emerging technology of Web services, we shouldn't be surprised to find that they do exist, at least for today.

Using the Session object requires specifying the EnableSession parameter

To use the Session object, although not the others, a method within this class must also specify the EnableSession parameter in its WebMethod attribute. For example, if the Factorial method in the Compute class shown earlier were to do this, its declaration would look like this:

 [WebMethod(EnableSession=true)]     public int Factorial(int f)     {  ...} 

Web services applications can also use transactions

Here's another concern: What if a method exposed as a Web service needs to group the work it does into a transaction? If the method uses ADO.NET to access a DBMS, it can certainly use the services of the Connection and Transaction objects to demarcate transaction boundaries, just like any other ADO.NET client. But suppose the method needs to create a transaction that spans multiple DBMSs or includes work done by other components? In the .NET Framework, these services are provided by the classes in System.EnterpriseServices, as described in Chapter 5, and ultimately by COM+. To access these services, a method exposed as a Web service can use another parameter of the WebMethod attribute called TransactionOption. If a method to transfer money between two bank accounts were exposed as a Web service, for example, that method might be declared like this:

 [WebMethod(TransactionOption=     TransactionOption.Required)] public bool MoveMoney(int fromAccount,     int toAccount, decimal amount) {  ... } 

When the method executes, it will automatically run within a transaction managed by code in System.EnterpriseServices. It's important to note that this transaction includes only the work done by the MoveMoney method, which might, say, add to one account and subtract from another. It does not involve the client, whose only role is to call MoveMoney. The value of transactions that span SOAP calls is an open topic today, one on which reasonable people can disagree. While a way to do this might one day exist, currently the TransactionOption property controls only conventional COM+-based transactions.

Transactions don't span SOAP calls

Another issue that might confront the creator of a Web services method is how to deal with SOAP headers. As Chapter 2 described, a SOAP packet can include various headers, and each of those headers can have a mustUnderstand attribute. Given that SOAP headers are allowed to contain virtually anything, ASP.NET provides quite generic support for working with them. The foundation of that support is the SoapHeader class, contained in the namespace System.Web.Services.Protocols. This class defines common properties found in a SOAP header, including a MustUnderstand property to contain the value of a header's mustUnderstand attribute. By inheriting from this class, a developer can more easily create a class that reflects the specifics of a particular SOAP header. To populate an instance of a SoapHeader class, a SoapHeader attribute can be added to a Web method's definition, identifying a variable of the appropriate header class. When a SOAP packet that contains this header is received, the header's information will be copied into the SoapHeader class, allowing the method to examine it.

ASP.NET supports processing SOAP headers

A Web services application can define its own namespace

One more concern stems from every Web service's dependence on XML, the representation for all information sent and received via SOAP. This information, including method names and more, will belong to a default XML namespace unless an explicit alternative is provided. It's a good idea to provide this alternative since XML namespaces are used to differentiate between information carried by different services. The WebService attribute, defined in System.Web.Services, can be applied to the class, with the attribute's Namespace parameter used to specify the XML namespace. For example, if the Compute class shown earlier were provided by the fictitious QwickBank, its declaration might look like this:

 [WebService(Namespace=     "http://www.qwickbank.com/mathinfo")] public class Compute {  . . . } 

Recall that even though it looks like a URL, an XML namespace identifier is actually a URI. Typing this identifier into a browser isn't guaranteed to lead anywhere at all it's just a convenient way to specify a unique name.

Microsoft-Specific Support for Web Services Applications

The basic standards for Web services are largely complete today, and ASP.NET supports them quite well. SOAP and WSDL are an intrinsic part of ASP.NET, as already described. Visual Studio.NET also has built-in support for accessing a UDDI registry on the Internet to find and add references for publicly available Web services. But given the nascent state of Web services, most vendors who implement them add some extras, and Microsoft is no exception.

One option ASP.NET provides is the ability to access Web services using pure HTTP rather than sending SOAP messages over HTTP. If HTTP's GET method is used, a call's parameters are passed in a simple form not XML as part of the URL string handed to the server. If HTTP's POST method is used, a call's parameters are passed in the body of the HTTP message, with each parameter identified by name. For clients that are unable to bear the weight of SOAP, these simpler protocol choices might be useful.

ASP.NET allows invoking Web services using just HTTP

Another addition is the simpler alternative to UDDI called Disco, mentioned in Chapter 2. Intended for discovering available Web services on a single machine or in a local environment, Disco uses a simple XML-defined format to describe available Web services and access their WSDL descriptions. Visual Studio.NET automatically produces Disco files and just as with UDDI, allows searching for and adding references to Web services with Disco descriptions. Without a Web service's WSDL definition, it's tough to build a client for that service. Given both the early state of UDDI and its relative complexity, Microsoft has chosen also to provide this simple, concrete mechanism for discovering Web services in a more localized environment.

Disco provides a straightforward way to learn about available Web services

< BACK  NEXT >


Understanding. NET. A Tutorial and Analysis
Understanding .NET: A Tutorial and Analysis (Independent Technology Guides)
ISBN: 0201741628
EAN: 2147483647
Year: 2002
Pages: 60

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