Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C# ПІДРУЧНИКИ / c# / Hungry Minds - ASP.NET Bible VB.NET & C#

.pdf
Скачиваний:
128
Добавлен:
12.02.2016
Размер:
7.64 Mб
Скачать

ToUnits});

return ((System.Decimal)(results[0]));

The first line of code calls the Invoke method of the proxy class to synchronously call the CTemp Web service and return the result. The second line of code converts the result to the proper type (Decimal) and returns this result to the caller.

Of course, our call to the CTemp proxy, which in turn calls the actual CTemp Web service method, is all marshaled on our local Web server using XML, HTTP, and SOAP. However, our proxy class could just as easily have been calling the CTemp Web service on a machine in another room, across the country, or even halfway around the world! This distinction is completely hidden from the consumer of the Web service as well as the fact that the proxy is exchanging SOAP messages with the CTemp Web service. All we have to do is create an instance of the proxy class and invoke its methods as if it were a local class. What could be easier?

Given a valid proxy class, we can now compile this class into a .NET assembly using the appropriate language compiler. Again, you will need the servi ces of a command prompt window, because all .NET compilers have command-line interfaces. Just as we did previously, start a command prompt window and change your current directory to that of your client application folder (inetpub\wwwroot\CTempClient). After doing so, execute the following command, appropriate for the language you are using.

VB.NET:

vbc /t:library /out:bin\CTempProxy.dll

/r:System.Web.Services.dll

/r:System.XML.dll /r:System.dll CTempProxy.vb

C#:

csc /t:library /out:bin\CTempProxy.dll

/r:System.Web.Services.dll

/r:System.XML.dll /r:System.dll CTempProxy.cs

Tip The .NET compilers are installed in WINNT\System32\Microsoft.NET\version by default. To reference them without a complete path prefix, you might wish to add this path to the system PATH environment variable on your computer. This also simplifies references to .NET assemblies using the /r option.

This command will compile the CTemp Web service proxy class into a .NET assembly that we can then reference from our Web Forms client application. The /t:library option specifies that we wish to create a DLL (rather than an executable). The /r option specifies the .NET assemblies that correspond to the .NET namespaces referenced by the proxy class. The /out option saves the assembly in the Web application's .\bin folder.

Figure 28-3 shows the results of executing the VB.NET compiler to build the CTemp proxy class assembly.

Figure 28-3: VB.NET compiler output

If you refer back to the proxy class, you will discover that the CTemp proxy class implements two additional methods named BeginCTemp and EndCTemp. These methods provide the support necessary to invoke the CTemp Web service asynchronously.

We will look at these and other features of the proxy class a little later in this chapter. For now, let's get back to building our client application by building a simple user interface form that can be used to interact with our CTemp Web service.

As mentioned earlier, you have many choices for the type of consumer application that is capable of calling methods of a Web service. In this instance, we will create an ASP.NET Web Forms Application to consume our CTemp Web service.

Building the Web form

Now that we have created a virtual directory, obtained the WSDL document, and created and built a proxy class for our consumer application, we are ready to build a form that will allow us to enter values that can be passed to the CTemp Web service and display the results after a successful call is completed.

For our ASP.NET Web Forms application, we will be using the following ASP.NET server controls:

§Two text boxes (one for the input temperature and one for the output temperature)

§Two radio button lists (one to select the input temperature units and one to select the output temperature units)

§One command button to initiate the units conversion

ASP.NET Web forms are contained in ASPX files. Let's begin creating our consumer application by creating a Web form based on the server controls mentioned previously. Enter the following code into your favorite text editor and save it in the Web application folder using the file name CTempClient.aspx:

<HTML>

<HEAD>

<title>CTemp Web Service Consumer Application</title>

</HEAD>

<body>

<form id="frmCTemp" action="CTempClient.aspx" runat="server">

<asp:textbox id="txtInputTemp" style="POSITION: absolute; TOP:

48px; LEFT: 10px;" Height="26px" Width="65px" runat="server"></asp:textbox>

<asp:radiobuttonlist id="optToUnits" style="POSITION: absolute;

TOP: 12px; LEFT: 347px;" runat="server">

<asp:ListItem Value="F">Fahrenheit</asp:ListItem>

<asp:ListItem Value="C" Selected="True">Celsius</asp:ListItem>

<asp:ListItem Value="K">Kelvin</asp:ListItem>

<asp:ListItem Value="R">Rankine</asp:ListItem>

</asp:radiobuttonlist>

<asp:radiobuttonlist id="optFromUnits" style="POSITION: absolute;

TOP: 36px; LEFT: 76px;" runat="server">

<asp:ListItem Value="F" Selected="True">Fahrenheit</asp:ListItem>

<asp:ListItem Value="C">Celsius</asp:ListItem>

</asp:radiobuttonlist>

<asp:button id="btnConvert" style="POSITION: absolute; TOP: 49px;

LEFT: 174px;" Text="Converts To" OnClick="btnConvert_Click" runat="server"></asp:button>

<asp:textbox id="txtOutputTemp" style="POSITION: absolute; TOP: 48px;

LEFT: 281px;" Height="28px" Width="66px" ReadOnly="True" runat="server"></asp:textbox>

</form>

</body>

</HTML>

This is a simple form that will allow the user to specify a temperature value, the source units, and the desired target units. The button will allow the user to submit the request to the server for processing. Note that, so far, nothing in the form is tied to a specific implementation language. Shortly, we will be able to add our implementation code to this form using any language that we choose, without having to change our form definition at all.

Let's take a brief look at these elements of our ASP.NET form to point out some of the highlights to you.

First, note that all the server controls specify a unique ID via the id attribute. This enables us to reference these controls by name within server code, which we'll add in a moment. Also, all server controls are marked with the runat="server" attribute.

The txtOutputTemp text box will be used to display the temperature conversion value returned by a call to the CTemp Web service. This text box specifies the ReadOnly property, which prevents users from modifying the text in the text box (because this will be set to the appropriate value by the form after obtaining the results of the unit conversion).

The btnConvert button, when clicked by the user, will execute the units conversion based on the settings chosen by the user in the other controls. The Text property is used to display the "Converts To" string on the face of the button. Note that the OnClick property specifies the name of the event handler when this button is clicked. In this case, the btnConvert_Click procedure will be executed.

Next, we have two sets of option list controls. The optFromUnits control displays two entries in its list: one named Celsius with a value of C and one named Fahrenheit with a value of F. Note that the Fahrenheit item has been identified as the default value via the Selected property so that this entry is selected by default when the form is displayed for the first time.

The optToUnits control displays four entries in its list: one named Fahrenheit (value F), one named Celsius (value C), one named Kelvin (value K), and one named Rankine (value R). The Celsius item's Selected property is set to True so that this entry is selected by default when the form is displayed for the first time.

Now that we have our Web form created and initialized, we are ready to add the code to the form that will create an instance of the CTemp proxy class and allow us to interact with the proxy class to perform temperature unit conversions.

Creating an instance of the proxy class

To call methods of the proxy class that represents the Web service, you must create an instance of the proxy class. As it turns out, creating an instance of a Web service proxy is identical to creating an instance of any other .NET class, which, as you will see, is quite easy.

To create an instance of the CTemp proxy class, we simply reference the class definition in our declaration. Let's illustrate this process by adding some code to the Web form application we have been building.

The first step we need to complete is to import the namespace of the assembly that contains our CTemp proxy class implementation. This is done using ASP.NET's @Import page directive. Add the following line to the top of your CTempClient.aspx file:

<% @ Import Namespace="CTempProxy" %>

This will enable us to reference the class in our code. Recall that when we generated our proxy class using the wsdl tool, we provided a namespace for the proxy class. This is the same namespace that we have specified to the Import directive.

We are now ready to add the code that will handle the OnClick event of the btnConvert server control. Insert the following code between the <html> and <head> tags of your Web form.

VB.NET:

<script language="VB" runat="server">

Sub btnConvert_Click(sender As Object, e As EventArgs)

Dim TC As New TempConverter()

txtOutputTemp.Text = Format(TC.CTemp(CType(txtInputTemp.Text, _

Decimal), optFromUnits.SelectedItem.Value, _

optToUnits.SelectedItem.Value), "Fixed")

End Sub

</script>

C#:

<script language="CS" runat="server">

void btnConvert_Click(Object Src, EventArgs E) {

TempConverter TC = new TempConverter();

txtOutputTemp.Text =

TC.CTemp(Convert.ToDecimal(txtInputTemp.Text),

optFromUnits.SelectedItem.Value,

optToUnits.SelectedItem.Value).ToString("F");

}

</script>

This code shows that the TC variable is declared to be an instance of the CTemp proxy class denoted by the TempConverter class declaration. Following this decla ration is a single line of code that extracts the input arguments from the Web form, calls the CTemp method on the TempConverter proxy class (the synchronous form), formats the results, and inserts the value into the output text box.

Let's take a closer look at the code that actually invokes the CTemp method on the proxy class.

Calling the CTemp proxy method

ASP.NET Web services can be called both synchronously and asynchronously. A synchronous method call is characterized by the fact that the caller waits for a response from the Web service before continuing execution. An asynchronous method call, on the other hand, permits the caller to continue with other work while the call is in progress. A notification mechanism is then used to inform the consumer that the Web service call has completed.

ASP.NET Web services use HTTP and SOAP as the default transport protocol and messaging format, respectively, because it provides for the exchange of a much larger family of data types, as well as complex XML-based document types. The proxy class, of course, eliminates the details of XML serialization, SOAP message formats, and HTTP request/response exchanges from the caller, making it quick and easy to call Web service methods.

To call a Web service method on our proxy class, all we need do is specify the name of the method to call (along with any arguments) using the reference to the instance of the proxy that we declared.

In our example, we are calling the synchronous form of the CTemp Web method to convert temperature units as follows.

VB.NET:

txtOutputTemp.Text = Format(TC.CTemp(CType(txtInputTemp.Text, _

Decimal), optFromUnits.SelectedItem.Value, _

optToUnits.SelectedItem.Value), "Fixed")

C#:

TxtOutputTemp.Text = TC.CTemp(Convert.ToDecimal(txtInputTemp.Text),

optFromUnits.SelectedItem.Value,

optToUnits.SelectedItem.Value).ToString("F");

Let's break down this statement into its fundamental parts so that we can thoroughly examine everything that is occurring in this code:

§The proxy object reference (TC) is used to call the CTemp method (TC. CTemp).

§The first argument to the CTemp method specifies the input temperature. This value is obtained from the text box on the Web form by referring to the Text property of the text box control (txtInputTemp.Text).

§The CTemp method expects the input temperature argument to be of type Decimal, so the text obtained from the text box control is converted into the Decimal data type.

§The second argument to the method specifies the source units of the temperature value. This value is obtained from the option button list by using the SelectedItem property to reference the currently selected option button and then referencing the Value property of that result (optFromUnits.SelectedItem.Value). This returns a single character string that encodes the source units as either F (for Fahrenheit) or C (for Celsius).

§The third argument to the method specifies the target units of the temperature conversion. This value is obtained from the option button list by using the SelectedItem property to reference the currently selected option button and then referencing the Value property of that result (optToUnits.SelectedItem.Value). This returns a single character string that encodes the target units as either F, C, K (for Kelvin), or R (for Rankine).

§Lastly, the Decimal result that is returned by the method call is

converted to a formatted text string using a built-in "Fixed" numeric formatter. This results in a text string that displays at least one digit to the left of the decimal separator and two digits to the right. This string is then assigned to the Text property of the output text box (txtOutputTemp.Text).

This tiny bit of code handles the entire process of gathering the input from the Web form controls, converting this input to the proper data types expected by the CTemp method call, calling the method, formatting the result, and assigning it to the text box control on the Web form that displays the results of the call.

Those of you who are familiar with programming forms in Visual Basic 6 (or earlier) will notice that the programming model for ASP.NET Web Forms is strikingly similar to programming Windows Forms in previous versions of Visual Basic. What's more, interacting with Web services is very much like interacting with traditional COM automation components. This is not an accident. The designers of the .NET Framework and ASP.NET worked very hard to ensure that the skills you have gained from building traditional Windows applications can be leveraged when building the next generation of applications based on the .NET Framework.

We now have a simple, but complete Web service consumer application that is capable of collecting input from a user via a Web form and processing this input by calling our CTemp Web service. With the code in place, let's take a look at how we can test our application.

Testing the Consumer Application

Now that you have created the consumer application, designed the Web form, and added the code to the Click event of the button control, you are ready to test your application.

To test our application, simply start an instance of the Internet Explorer Web browser and type the following URL into the Address bar:

http://localhost/ctempclient/ctempclient.aspx

This displays our client application's Web form, as shown in Figure 28-4.

Figure 28-4: CTemp client user interface

To test the application, enter a temperature value in the first text box, select the source units, select the target units, and then click the Converts To button. The Web form is submitted to the server, where the Click event code of the button is executed. This code creates an instance of the CTemp proxy class, calls the CTemp method, and outputs the conversion results to the target temperature text box. Figure 28-5 shows the results of calling the CTemp Web service with some sample input.

Figure 28-5: Results of temperature conversion

Having now seen our consumer application in action, let's take a look at the larger picture of what really happens when we run our application to interact with the CTemp Web service.

Application Execution Model

Seeing how simple it was to create a consumer for our CTemp Web service, you might be tempted to forget all that is actually taking place when calling a Web service method. The real value of the .NET Framework and ASP.NET is quite evident when we examine some of the details behind the operation of our simple consumer application and Web service.

Let's take a quick look at what happens during the execution lifetime of the consumer application and the Web service as it processes a single temperature conversion request.

Recall that both Web services and Web applications are really ASP.NET applications and, thus, run under the control of ASP.NET and the CLR. As such, both applications are contained in a virtual directory on a Web server, with the appropriate files for each application stored in the root of the virtual directory along with any needed assemblies, which are stored in the bin folder of the virtual directory.

The consumer application is started when a user requests the main form of the application. We will start our journey at this point.

1.A user requests the main form of the CTempClient application, such as http://localhost/CTempClient/CTempClient.aspx.

2.The IIS Web server on localhost receives the request (technically, an HTTP GET request) and hands it off to the ASP.NET runtime for execution of the page (because the requested page has an .aspx extension). This handoff occurs via an ISAPI filter extension that is registered within IIS to handle all of the ASP.NET file types.

3.The ASP.NET runtime creates an instance of the page class that represents the Web form and executes the page.

4.The page class generates the HTML and sends it to the browser, causing the form to be rendered in the user's browser window.

5.The page class is then destroyed by the ASP.NET runtime along with any other necessary request cleanup processing (remember, HTTP is a stateless protocol, so there is no need to keep the page class around after the HTML has been transmitted to the client).

6.The user enters information into the form and presses the Convert To button. This causes the form to be posted back to the Web server.

7.Again, the Web server hands off the request (technically, an HTTP POST request) to the ASP.NET runtime, which creates a new instance of the page class that implements the Web form and executes the page.

8.This time (because this is a postback request) the server-side button control's Click event code is now executed. Recall that this is where we added our code to create and call the CTemp Web service.

9.The Click event code creates an instance of the CTemp Web service proxy class. This class inherits from the System.Web.Services.Protocols.SoapHttpClientProtocol class. This provides the foundation for communicating the method request and response via SOAP messages over the HTTP transport.

10.The Click event code now calls the synchronous CTemp method on the proxy object, passing the input arguments obtained from the postback data of the form (via server-side control properties).

11.The Web service proxy calls the Invoke method, passing along the input arguments. This method serializes the CTemp method call into a SOAP message that matches the method signature defined in the WSDL document. The SOAP message is then added to the payload of an HTTP request and delivered to the Web service endpoint (the URL of the ASMX file).

12.The IIS Web server that hosts the CTemp Web service (in this specific case, localhost) receives the request (technically, a SOAP POST request) and hands it off to the ASP.NET runtime to execute the requested page.

13.The ASP.NET runtime deserializes the SOAP payload from the request, creates an instance of the CTemp Web service implementation class, and executes the CTemp method, passing the input arguments.

14.Next, the ASP.NET runtime takes the result of the CTemp method call and serializes it into a SOAP response message. This message is then added to the payload of an HTTP response and delivered back to the client (in this case, our proxy class).

15.The Invoke method of the proxy class deserializes the result from the SOAP response message into a generic .NET Object type. This type is then explicitly cast to the return data type expected by the caller (in this case, a Decimal temperature value) and returned to our consumer application.

16.The Click event code in our consumer application takes the result, converts it to the String data type, and assigns the result to the output text box in the Web form, formatted to two decimal places. The event code processing is now completed and page execution continues.

17.The page now executes through its rendering phase to generate the HTML that is returned to the user's browser. Just as before, the page class is then torn down by the ASP.NET runtime and any other cleanup processing that is necessary is executed.

Whew! That was a handful! Hopefully, this simulated flow of execution between a Web service and its consumer will give you a solid foundation for further exploration into the underpinnings of how Web services work. This information will also be useful as you build Web services and/or consumers and need to troubleshoot problems that might arise.

Summary

As we have demonstrated in this part of ASP.NET Bible, Web services are poised to become the programmable building blocks for the next generation of the Internet. The wide adoption of XML, HTTP, and SOAP has made it possible to create an object middleware infrastructure that is easily capable of being leveraged on the many types of systems attached to the Internet, regardless of hardware platform, operating system, or object model. Even more important, a consistent and simple way to interact with these programmable components finally exists.

Having this new level of interoperability at a programming level will enable the creation of many new and innovative solutions to problems that were once difficult, if not impossible, to address in the past. It is only a matter of time before we will have, at our fingertips, a huge library of these programmable building blocks from which to construct truly distributed applications that can interoperate with all kinds of systems.

In many respects, it is up to us, professional programmers, to create these building blocks. Web services give you a powerful tool to construct these building blocks in a way that greatly expands the potential population of consumers that can leverage these services.

Part V: Building ASP.NET Applications

Chapter List

Chapter 29: ASP.NET Blackjack

Chapter 30: Chatty Discussion Forum

Chapter 29: ASP.NET Blackjack

Overview

Writing games is great fun. Not surprisingly, many developers originally became interested in computer programming because of their love for computer games. I know I did!

But writing games is not a trivial task. In fact, professional game programming is one of the most challenging fields in software development. But, aside from being an enjoyable pastime, why should those of us whose primary work responsibilities are business applications spend time writing games?

I've found that writing games is a great way to explore a new language or set of programming tools. Games often exercise a variety of user interface components, data structures, and programming constructs. In short, they give your brain the workout it needs to really begin to explore and understand a new development environment.

With that in mind, I've created an ASP.NET blackjack game to demonstrate a number of important ASP.NET features. Blackjack is a relatively simple card game with well-defined rules, so it's a perfect candidate for helping you to understand what all the various pieces and parts of ASP.NET do, how they fit together, and what their roles are in creating applications.

Blackjack: The Rules

If you are familiar with blackjack rules, feel free to skim or skip this section.

Blackjack, also called 21, is a card game involving one dealer and one or more players. Although any number can play, players do not play against each other. Each one plays individually against the dealer.

The goal of blackjack is to draw cards with values totaling as close to 21 as possible without going over (referred to as busting). In the end, if your total is higher than the dealer's, you win. If you bust or your total is less than the dealer's, you lose.

You begin with two cards. You can choose to hit (draw another card) or stand (stay with your current total). You can hit as many times as you like until you either get 21 on the nose (and win!) or choose to stand on your current total. Once you stand, the dealer plays his or her turn and has the same options.

Face cards count as 10 and aces count as either 1 or 11, whichever works best for you. All the rest of the cards are valued based on their number. When your first two cards are a face card (or a 10) and an ace, you have 21 right off the bat, called a blackjack!

When you begin, you are allowed to see what the dealer's first card is. You can use this information, if you like, to decide how aggressively or conservatively you want to play. Here's a basic strategy that is designed to play the odds to your best advantage: if the dealer's first card is a good one (7-10, face card, or an ace), you should play more aggressively and keep hitting until you get to 17 or better (or bust). If the dealer's first card is a bad one (2-6), then you should play conservatively and stop hitting when you get to 12 or better. The idea is that if the dealer's first card is bad, the dealer is more likely to bust in the end. And if the dealer busts, you win, no matter what your total is. But, again, this is just one strategy — when you play, you can choose to hit or stand whenever you like.

Playing a Hand or Two

Now that you know how to play, you are ready to walk through a demonstration of the blackjack application.

As the game begins, you have already received two cards and you can see the dealer's first card (see Figure 29-1).

Figure 29-1: The game begins.

At this point, you have two options: Hit or Stand, as indicated by the buttons. If you click Hit, another card is dealt (see Figure 29-2).

Figure 29-2: Hit me.

Соседние файлы в папке c#