Tải bản đầy đủ (.pdf) (10 trang)

Professional ASP.NET 3.5 in C# and Visual Basic Part 140 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (210.32 KB, 10 trang )

Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1353
Chapter 29: Building and Consuming Services
In this example, the
SoapHeader
attribute takes a
string
value of the name of the instantiated
SoapHeader
class — in this case,
myHeader
.
From here, the
WebMethod
actually makes use of the
myHeader
object. If the
myHeader
object is not found
(meaning that the client did not send in a SOAP header with his constructed SOAP message), a simple
‘‘
Hello World
’’ is returned. However, if values are provided in the SOAP header of the SOAP request,
those values are used within the returned
string
value.
Consuming a Web Service Using SOAP Headers
It really is not difficult to build an ASP.NET application that makes a SOAP request to a Web service
using SOAP headers. Just as with t he Web services that do not include SOAP headers, you make a Web
Reference to the remote Web service directly in Visual Studio.
For the ASP.NET page, create a simple page with a single Label control. The output of the Web service is
placed in the Label control. The code for the ASP.NET page is shown in Listing 29-19.


Listing 29-19: An ASP.NET page working with an XML Web s ervice using SOAP headers
VB
<%@ Page Language="VB" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ws As New localhost.HelloSoapHeader()
Dim wsHeader As New localhost.HelloHeader()
wsHeader.Username = "Bill Evjen"
wsHeader.Password = "Bubbles"
ws.HelloHeaderValue = wsHeader
Label1.Text = ws.HelloWorld()
End Sub
</script>
<html xmlns=" >
<head runat="server">
<title>Working with SOAP headers</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" Runat="server"></asp:Label>
</div>
</form>
</body>
</html>
C#
<%@ Page Language="C#" %>
<script runat="server">
Continued
1353

Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1354
Chapter 29: Building and Consuming Services
protected void Page_Load(object sender, System.EventArgs e) {
localhost.HelloSoapHeader ws = new localhost.HelloSoapHeader();
localhost.HelloHeader wsHeader = new localhost.HelloHeader();
wsHeader.Username = "Bill Evjen";
wsHeader.Password = "Bubbles";
ws.HelloHeaderValue = wsHeader;
Label1.Text = ws.HelloWorld();
}
</script>
Two objects are instantiated. The first is the actual Web service,
HelloSoapHeader
. The second, which
is instantiated as
wsHeader
,isthe
SoapHeader
object. After both of these objects are instantiated and
before making the SOAP request in the application, you construct the SOAP header. This is as easy as
assigning values to the
Username
and
Password
properties of the
wsHeader
object. After these properties
are assigned, you associate the
wsHeader
object to the

ws
object through the use of the
HelloHeaderValue
property. After you have made the association between the constructed SOAP header object and the
actual
WebMethod
object (
ws
), you can make a SOAP request just as you would normally do:
Label1.Text = ws.HelloWorld()
Running the page produces the result in the browser shown in Figure 29-16.
Figure 29-16
What is more interesting, however, is that the SOAP request reveals that the SOAP header was indeed
constructed into the overall SOAP message, as shown in Listing 29-20.
Listing 29-20: The SOAP request
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap=" />xmlns:xsi=" />xmlns:xsd=" /><soap:Header>
<HelloHeader xmlns=" /><Username>Bill Evjen</Username>
<Password>Bubbles</Password>
1354
Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1355
Chapter 29: Building and Consuming Services
</HelloHeader>
</soap:Header>
<soap:Body>
<HelloWorld xmlns=" />
</soap:Body>
</soap:Envelope>
This returns the SOAP response shown in Listing 29-21.
Listing 29-21: The SOAP response

<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap=" />xmlns:xsi=" />xmlns:xsd=" /><soap:Body>
<HelloWorldResponse xmlns=" /><HelloWorldResult>Hello Bill Evjen. Your password is:
Bubbles</HelloWorldResult>
</HelloWorldResponse>
</soap:Body>
</soap:Envelope>
Requesting Web Services Using SOAP 1.2
Most Web services out there use SOAP version 1.1 for the construction of their messages. With that
said, SOAP 1.2 became a W3 C recommendation in June 2003 (see
www.w3.org/TR/soap12-part1/
).
The nice thing about XML Web services in the .NET Framework platform is that they are capable of
communicating in both the 1.1 and 1.2 versions of SOAP.
In an ASP.NET application that is consuming a Web service, you can control whether the SOAP request
is constructed as a SOAP 1.1 message or a 1.2 message. Listing 29-22 changes the previous example so
that the request uses SOAP 1.2 instead of the default setting of SOAP 1.1.
Listing 29-22: An ASP.NET application making a SOAP request using SOAP 1.2
VB
<%@ Page Language="VB" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ws As New localhost.HelloSoapHeader()
Dim wsHeader As New localhost.HelloHeader()
wsHeader.Username = "Bill Evjen"
wsHeader.Password = "Bubbles"
ws.HelloHeaderValue = wsHeader
ws.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap12
Label1.Text = ws.HelloWorld()
Continued

1355
Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1356
Chapter 29: Building and Consuming Services
End Sub
</script>
C#
<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, System.EventArgs e) {
localhost.HelloSoapHeader ws = new localhost.HelloSoapHeader();
localhost.HelloHeader wsHeader = new localhost.HelloHeader();
wsHeader.Username = "Bill Evjen";
wsHeader.Password = "Bubbles";
ws.HelloHeaderValue = wsHeader;
ws.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap12;
Label1.Text = ws.HelloWorld();
}
</script>
In this example, you first provide an instantiation of the Web service object and use the new
SoapVer-
sion
property. The property takes a value of
System.Web.Services.Protocols.SoapProtocolVersion
.Soap12
to work with SOAP 1.2 specifically.
With this bit of code in place, the SOAP request takes the structure shown in Listing 29-23.
Listing 29-23: The SOAP request using SOAP 1.2
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap=" />xmlns:xsi=" />xmlns:xsd=" /><soap:Header>
<HelloHeader xmlns=" /><Username>Bill Evjen</Username>

<Password>Bubbles</Password>
</HelloHeader>
</soap:Header>
<soap:Body>
<HelloWorld xmlns=" />
</soap:Body>
</soap:Envelope>
One difference between the two examples is the
xmlns:soap
namespace that is used. The difference actu-
ally resides in the HTTP header. When you compare the SOAP 1.1 and 1.2 messages, you see a difference
in the
Content-Type
attribute. In addition, t he SOAP 1.2 HTTP header does not use the
soapaction
attribute because this is now combined with the
Content-Type
attribute.
You can turn off either SOAP 1.1 or 1.2 capabilities with the Web services that you build by making the
proper settings in the
web.config
file, as shown in Listing 29-24.
1356
Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1357
Chapter 29: Building and Consuming Services
Listing 29-24: Turning off SOAP 1.1 or 1.2 capabilities
<configuration xmlns=" /><system.web>
<webServices>
<protocols>
<remove name="HttpSoap"/> <! Removes SOAP 1.1 abilities >

<remove name="HttpSoap1.2"/> <! Removes SOAP 1.2 abilities >
</protocols>
</webServices>
</system.web>
</configuration>
Consuming Web Services Asynchronously
All the Web services that you have been working with in this chapter have been done synchronously.This
means that after a request is sent from the code of a n ASP.NET application, the application comes to a
complete standstill until a SOAP response is received.
The process of invoking a
WebMethod
and getting back a result can take some t ime for certain requests. At
times, you are not in control of the Web service from which you are requesting data and, therefore, you
are not in control of the performance or response t imes of these services. For these reasons, you should
consider consuming Web services asynchronously.
An ASP.NET application that makes an asynchronous request can work on other programming tasks
while the initial SOAP request is awaiting a response. When the ASP.NET application is done working
on the additional items, it can return to get the result form the Web service.
The great news is that to build an XML Web service that allows asynchronous communication, you
don’t have to perform any additional actions. All
.asmx
Web services have the built-in capability for
asynchronous communication with consumers. The Web service in Listing 29-25 is an example.
Listing 29-25: A slow Web service
VB
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1,
EmitConformanceClaims:=True)> _

Public Class Async
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function HelloWorld() As String
System.Threading.Thread.Sleep(1000)
Return "Hello World"
Continued
1357
Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1358
Chapter 29: Building and Consuming Services
End Function
End Class
C#
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
[WebService(Namespace = " />[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Async : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld() {
System.Threading.Thread.Sleep(1000);
return "Hello World";
}
}
This Web service returns a simple
Hello World
as a string, but before it does, the Web service makes a
1000-millisecond pause. This is done by putting the Web service thread to sleep using the

Sleep
method.
Next, take a look at how an ASP.NET application can consume this slow Web service asynchronously, as
illustrated in Listing 29-26.
Listing 29-26: An ASP.NET application consuming a Web service asynchronously
VB
<%@ Page Language="VB" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ws As New localhost.Async()
Dim myIar As IAsyncResult
myIar = ws.BeginHelloWorld(Nothing, Nothing)
Dim x As Integer = 0
Do Until myIar.IsCompleted = True
x+=1
Loop
Label1.Text = "Result from Web service: " & ws.EndHelloWorld(myIar) & _
"<br>Local count while waiting: " & x.ToString()
End Sub
</script>
1358
Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1359
Chapter 29: Building and Consuming Services
<html xmlns=" >
<head runat="server">
<title>Async consumption</title>
</head>
<body>
<form id="form1" runat="server">
<div>

<asp:Label ID="Label1" Runat="server"></asp:Label>
</div>
</form>
</body>
</html>
C#
<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, System.EventArgs e) {
localhost.Async ws = new localhost.Async();
IAsyncResult myIar;
myIar = ws.BeginHelloWorld(null, null);
int x = 0;
while (myIar.IsCompleted == false) {
x+=1;
}
Label1.Text = "Result from Web service: " + ws.EndHelloWorld(myIar) +
"<br>Local count while waiting: " + x.ToString();
}
</script>
When you make the Web reference to the remote Web service in the consuming ASP.NET application,
you not only see the
HelloWorld WebMethod
available to you in IntelliSense, you also see a
BeginHel-
loWorld
and an
EndHelloWorld
. To work with the Web service asynchronously, you must utilize the
BeginHelloWorld

and
EndHelloWorld
methods.
Use the
BeginHelloWorld
method to send a SOAP request to the Web service, but instead of the ASP.NET
application waiting idly for a response, it moves on to accomplish other tasks. In this case, it is not doing
anything that important — just counting the amount of time it is taking in a loop.
After the SOAP request is sent from the ASP.NET application, you can use the
IAsyncResult
object
to check whether a SOAP response iswaiting.Thisisdonebyusing
myIar.IsCompleted
.Iftheasyn-
chronous invocation is not complete, the ASP.NET application increases the value of
x
by one before
making the same check again. The ASP.NET application continues to do this until the XML Web service
is ready to return a response. The response is retrieved using the
EndHelloWorld
method call.
Results of running this application are similar to what is shown in Figure 29-17.
1359
Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1360
Chapter 29: Building and Consuming Services
Figure 29-17
Windows Communication Foundation
Since the introduction of the .NET Framework 3.0, Microsoft has made available a new w ay to build Web
services beyond the ASP.NET-based Web services presented in this chapter.
Until the .NET Framework 3.0 came out, it was not a simple task to build components that were required

to communicate a message from one point to another because Microsoft offered more than one technol-
ogy that you could use for such an action.
For instance, you could have used ASP.NET Web services (as just seen), Web Service Enhancements
3.0 (WSE), MSMQ, Enterprise Services, .NET Remoting, and even the
System.Messaging
namespace.
Each technology has its own pros and cons. ASP.NET Web Services (also known as ASMX Web Services)
provided the capability to easily build interoperable Web services. The WSE enabled you to easily build
services that took advantage of some of the WS-* message protocols. MSMQ enabled the queuing of
messages, making it easy to work with solutions that were only intermittently connected. Enterprise
Services, provided as a successor to COM+, offered an easy means to build distributed applications.
.NET Remoting was a fast way to move messages from one .NET application to another. Moreover, these
are Microsoft options only. This does not include all the options available in other environments, such as
the Java world.
With so many options available to a Microsoft developer, it can be tough to decide which path to
take with the applications you are trying to build. With this in mind, Microsoft has created the Windows
Communication Foundation (WCF).
WCF is a new framework for building service-oriented applications. Microsoft wanted to provide its
developers with a framework to quickly get a proper service-oriented architecture up and running. Using
the WCF, you will be able to take advantage o f a ll the items that make distribution technologies powerful.
WCF is the answer and the successor to all these other message distribution
technologies.
The Larger Move to SOA
Upon examining WCF, you will find that it is part of a larger movement that organizations are making
toward the much talked about service-oriented architecture,orSOA. An SOA is a message-based service
architecture that is vendor agnostic. As a result, you have the capability to distribute messages across
1360
Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1361
Chapter 29: Building and Consuming Services
a system, and the messages are interoperable with other systems that would otherwise be considered

incompatible with the provider system.
Looking b ack, you can see the gradual progression to the service-oriented architecture model. In the
1980s, the revolution arrived with the concept of everything being an object. When object-oriented pro-
gramming came on the scene, it was enthusiastically accepted as the proper means to represent entities
within a programming model. The 1990s took that one step further, and the component-oriented model
was born. This enabled objects to be encapsulated in a tightly coupled manner. It was only recently that
the industry turned to a service-oriented architecture because developers and architects needed to take
components and have them distributed to other points in an organization, to their partners, or t o their
customers. This distribution system needed to have the means to transfer messages between machines
that were generally incompatible with one another. In addition, the messages had to include the ability
to express the metadata about how a system should handle a message.
If you ask 10 people what an SOA is, you’ll probably get 11 different answers, but there are some common
principles that are considered to be foundations of a service-oriented architecture:
❑ Boundaries are explicit: Any datastore, logic, or entity uses an interface to expose its data or
capabilities. The interface provides the means to hide the behaviors within the service, and the
interface front-end enables you to change this behavior as required without affecting down-
stream consumers.
❑ Services are autonomous: All the services are updated o r versioned independently of one
another. Thus, you do not upgrade a system in its entirety; instead, each component of these
systems is an individual entity within itself and can move forward without waiting for other
components to progress forward. Note that with this type of model, once you publish an inter-
face, that interface must remain unchanged. Interface changes require new interfaces (versio ned,
of course).
❑ Services are based upon contracts, schemas, and policies: All services developed require a con-
tract regarding what is required to consume items from the interface (usually done through a
WSDL document). Along with a contract, schemas are re quired to define the items passed in
as parameters or delivered through the service (using XSD schemas). Finally, policies define any
capabilities or requirements of the service.
❑ Service compatibility that is based upon policy: The final principle enables services to define
policies (decided at runtime) that are required to consume the service. These policies are usually

expressed through WS-Policy.
If your own organization is considering e stablishing an SOA, the WCF is a framework that works on
these principles and makes it relatively simple to implement. The next section looks at what the WCF
offers. Then you can dive into building your first WCF service.
WCF Overview
As stated, the Windows Communication Foundation is a means to build distributed applications in a
Microsoft environment. Although the distributed application is built upon that environment, this does
not mean that consumers are required to be Microsoft clients or to take any Microsoft component or
technology to accomplish the task of consumption. On the other hand, building WCF services means you
are also building services that abide by the principles set forth in the aforementioned SOA discussion
and that these services are vendor agnostic — thus, they are able to be consumed by almost anyone.
1361
Evjen c29.tex V2 - 01/28/2008 3:53pm Page 1362
Chapter 29: Building and Consuming Services
You can build WCF services using Visual Studio 2008. Note that because this is a .NET Framework
3.0 component, you are actually limited to the operating systems in which you can run a WCF service.
Whereas the other Microsoft distribution technologies mentioned in this chapter do not have too many
limitations on running on Microsoft operating systems, an application built with WCF can only run on
Windows XP SP2, Windows Vista, or Windows Server 2008.
Building a WCF Service
Building a WCF service is not hard to accomplish. If you are working from a .NET Framework 2.0 envi-
ronment, you need to install the .NET Framework 3.0. If you have installed t he . NET Framework 3.5,
then you will find that both the .NET Framework 2.0 and 3.0 have been installed also.
From there, it is easy to build WCF services directly in Visual Studio 2008 because it is already geared
to work with this application type. If you are working with Visual Studio 2005, you need to install the
Visual Studio 2005 extensions for .NET Framework 3.0 (WCF and WPF). Download these Visual Studio
extensions, if you are using Visual Studio 2005. Installing the extensions into Visual Studio 2005 adds a
WCF project to your IDE. If you are using Visual Studio 2008, the view of the project from the New Web
Site dialog box is presented in Figure 29-18.
Figure 29-18

When you build a WCF project in this manner, the idea is that you build a t raditional class library that is
compiled down to a DLL that can then be added to another project. The separation of code and project
is a powerful division on larger projects. That said, you can, however, just as easily build a WCF service
directly in your .NET project, whether that is a console application or a Windows Forms application. The
approach taken for the examples in this chapter show you how to build a WCF service that is hosted
in a console application. Keep in mind that for the services you actually build and deploy, it is usually
better to build them directly as a WCF Service Library project and use the created DLL in your projects or
in IIS itself.
1362

×