This article will open your eyes to the world of Web services. We will go over what Web services are and why to use them, as well as how to create them and how to tie into them using Flash MX 2004. And we will finish up by creating an application to search the Web using the Google API.
This article is an exerpt of the book Macromedia Flash MX Professional 2004 Unleashed, written by David Vogeleer and Matthew Pizzi. The article is reprinted by permission of the publisher (SAMS).
What Is a Web Service?
A Web service is exactly what it says; it’s a service on the Web. So what service do Web services provide? A Web service’s goal is to provide raw data in XML format to any application that makes a request to it. That may not make sense by itself, so here is exactly what a Web service does.
A Web service sits on a server much like any server-side page, and when a request is made to it, the Web service will perform a desired task, and return data in the form of XML. XML, as you learned in Chapter 21, “XML and Flash,” is a language that nearly any application can read because it is in fact a metalanguage made up of customized tags containing well-formed and structured data. And that is what a Web service is, and does, but that doesn’t explain why anyone should use them.
Why Use Web Services?
Some time ago, I was working on a sales force application that managed all the retail outlets for a client’s sales force. I made all the Flash pieces, and the objects necessary for it to work, but when I started testing it with live data, it wouldn’t return all the correct information. I looked through the database itself at the point where it was getting hung up, and lo and behold, there was an ampersand in not only one, but a few of the store names. Remember back in Chapter 20, “Introduction to Data Integration,” where you were introduced to data integration with Flash? You learned that name/value pairs are separated by ampersands. This means that when the parser reached the store name with the ampersand, it would think that part of the name was data, and the other part was the beginning of the next name/value pair like this:
The original store name: AB Grocery
Was thought to be: name=AB Grocery=<%@ WebService Language=”c#” debug=”true” class=”MyClass” %>using System.IO;
using System.Web.Services;
public class MyClass: System.Web.Services.WebService{
Notice that this class is public, which means it can be called from outside the service itself. After that, we use the class keyword and name our class MyClass. Then we begin to create the service with the System.Web.Services.WebService class. The next step is to begin declaring the Web methods. To do this, you use the keyword WebMethod in brackets, along with a description, if desired, that will help anyone looking at the Web service tell what each Web method is doing.
[WebMethod(Description=”Description of the Web method”)]
Then create the Web method itself declaring whether it is private or public. Before you name the Web method, you have to declare what data type will be returned. For example, the following will return an integer data type, so we use the keyword int:
public int myMethod(){
return 15;
}
}
Now that you have seen the basic parts of a Web service, we can begin to create them. The first Web service will simply return a string saying “hello.” So open your favorite text editor and place this code in it:
<%@ WebService Language=”c#” debug=”true” class=”Hello” %>
using System.IO;
using System.Web.Services;
public class Hello: System.Web.Services.WebService{
[WebMethod(Description=”Say hello”)]
public string sayHello() {
return “hello”;
}
}
The preceding code does everything we have discussed so far. It declares that we are creating a Web service in C#. It then gets the classes we need to use. After that, it creates the Hello class and then the method sayHello, which will send the string literal “hello” back to us.
Now save as hello.asmx in either your Web server or PWS (personal Web server). The directory on most Web servers including PWS’s is at c:inetpubwwwroot or one of its subdirectories. The .asmx extension is the extension for the Web services on .NET. Map to the new file using the browser, using http:// not file://, and you should see a screen similar to Figure 24.1.
NOTE
You must browse to Web services in order to view them in action. Otherwise, the browser will attempt to open them up in an application.
This screen is created automatically to help test the Web service without an application. You can see all the Web methods listed (in this case, just the sayHello method) and their description if it was declared. Select the sayHello method, and you will be taken to a screen that looks like Figure 24.2. Here you can invoke (run) the method to see its results. Also, you can see all the information about the method including its return value, and if we had any parameters, they would be shown here as well. Choose the Invoke button, and another browser window will pop up with XML data as shown in Figure 24.3. This is the result of the Web service. Now in this case, it’s not all that impressive, but as we move forward it will become so.

FIGURE 24.1 You can test your Web methods without an application.

FIGURE 24.2 The Web method information.

FIGURE 24.3 The results from the Web service.
And the final page to look at is the WSDL, so return to the original page, and at the top, choose the Service Description link, and the window will fill with more XML data as shown in Figure 24.4. This tells any user of the Web service everything they need to know to use it. It shows all the methods, their return values, and their parameters.

Consuming Web Services with Flash
Now that you see how to make a basic Web service, and how to test it, let’s take it a step further and bring the data into Flash.
We will begin working with the XML object to bring the data in, and finally move over to using Flash Remoting.
Using the XML Object
We went over the basics of the XML object back in Chapter 21. Now we are going to use it to consume our Web service that we have already created.
To absorb a Web service with the XML object, when you load it in, use the path to the Web service, followed by a slash, then the name of the Web method being called, like this:
myXML.load(“http://localhost/myWebService.asmx/myWebMethod”);
//create the XML object
var myXML:XML = new XML();
//ignore white space
myXML.ignoreWhite = true;
//create the event for when data is loaded
myXML.onLoad=function(){
myText_txt.text = this.firstChild.childNodes[0].nodeValue;
}
//load the web method result
myXML.load(“http://localhost/hello.asmx/sayHello”);
The preceding code first creates an XML object to absorb the Web service. It then sets the ignoreWhite property to true. After that, it creates the event callback for the XML object, so that when it receives data back, it will send the result to the text field. Finally, it loads the Web method.
Test the movie and you will see that the word “hello” has appeared in the text field.
NOTE
If you are running certain versions of the .NET framework, the preceding code may not work correctly by default. If this is the case, add this to the web.config file located on c::
<webServices>
<protocols>
<add name=”HttpGet”/>
</protocols>
</webServices>
Add the preceding code before the </system.web> closing tag, and then restart your computer.
That example demonstrated how to absorb a Web service with the XML object, but there is a much better way to do it using Flash Remoting.
Flash Remoting
As mentioned in Chapter 23, “Integrating ColdFusion with Flash,” Flash Remoting is a way of interacting with Web services in a whole new light. Instead of receiving XML back from the Web service, Flash Remoting returns objects that are easier to use and parse.
If you do not have Flash Remoting, you can download the free developer edition here. Also, for Flash Remoting to work, you will need the .NET Framework Redistributable installed, which can be found here. When you complete the download, a new directory in your local host directory will be created called flashremoting. This directory is important because it will hold the gateway we need to go through in order to use Flash Remoting. Now you will be able to absorb Web services with it instead of using the XML object.
When connecting to a Web service with remoting, we use a different path than we do with the XML object. We place the path in a string literal followed by a question mark and “WSDL”. This is how Flash Remoting connects to Web services.
Also, when retrieving results, you build a function with the same name as the Web method you want it to collect from followed by _Result.
For example, if you had a Web method called myWebMethod, you would collect the results like this:
myWebMethod_Result = function(result){
trace(result);
}
In the same file we just worked in, change the code in the first frame of the actions layer to this:
#include “NetServices.as”
#include “NetDebug.as”
//set the path for the gateway
gateway = “http://localhost/flashremoting/gateway.aspx”;
//create the gateway connection
myConn = NetServices.createGatewayConnection(gateway);
//set the path to the service
service = “http://localhost/hello.asmx?WSDL”;
//absorb the service
myServiceObject = myConn.getService(service, this);
//call the web method
myServiceObject.sayHello();
//when the web method receives results back
sayHello_Result = function(result){
myText_txt.text=result;
}
This code first includes the necessary remoting files. Then it sets the path for the gateway in a variable and creates the gateway connection. After that, it creates the path to the Web service and connects to it. We then create the function to handle the results from the Web method being returned. Finally, we call the Web method.
Test the movie again, and you will get the same results as the preceding example.Now that we are interacting successfully with our Web service, let’s actually make the Web service useful. In the following example, we will create a Web service that will accept a parameter, then square it, and return the results.
Open a text editor, create a new file and enter the following code, and then save the file to your Web root directory as squareService.asmx.
<%@ WebService Language=”c#” debug=”true” class=”Square” %>
using System.IO;
using System.Web.Services;
public class Square: System.Web.Services.WebService{
[WebMethod(Description=”Square the number”)]
public int squareNum(int sentNum) {
int myReturn = sentNum*sentNum;
return myReturn;
}
}
Much like our previous Web service, this one starts off by declaring that it is a Web service written in C#. It then grabs the object classes we need. Next, it declares the Web service class. After that, we declare the Web method and set its description. Then we create the Web method. Notice we declare that the result being returned will be an integer. And the parameter being sent will also be an integer.
Save this file, and then browse to it and choose the squareNum Web method. You will see a screen like Figure 24.5. As you can see, the Web service has provided a field where we can place a number to test, so enter the number 2004, and click Invoke. You should then see another browser screen like Figure 24.6 indicating that it worked.

Figure 24.5 The Web service provides a field to test the Web method.

Figure 24.6 Use parameters in Web methods to make Web services work for you.
Okay, now we have the Web service working, so let’s create the Flash application to use it.
#include “NetServices.as”
#include “NetDebug.as”
//set the path for the gateway
gateway = “http://localhost/flashremoting/gateway.aspx”;
//create the gateway connection
myConn = NetServices.createGatewayConnection(gateway);
//set the path to the service
service = “http://localhost/squareService.asmx?WSDL”;
//absorb the service
myServiceObject = myConn.getService(service, this);
//create the object to listen to the button component
var clickListen:Object = new Object();
//create the click event for the listener
clickListen.click = function(){
if(number_ti.text.length > 0){
//call the web method
myServiceObject.squareNum(Number(number_ti.text));
}else{
trace(“error”);
}
} //add the listener to the button component
square_pb.addEventListener(“click”, clickListen);
//when the web method receives results back
squareNum_Result = function(result){
results_ti.text=result;
}

#include “NetServices.as”
#include “NetDebug.as”
Next, we create the path to the gateway, make the connection, create the path to the Web service, and finally connect to the Web service through the gateway.
//set the path for the gateway
gateway = “http://localhost/flashremoting/gateway.aspx”;
//create the gateway connection
myConn = NetServices.createGatewayConnection(gateway);
//set the path to the service
service = “http://localhost/squareService.asmx?WSDL”;
//absorb the service
myServiceObject = myConn.getService(service, this);
Then we create an object to listen to the button being clicked. We then create the event for the listener that checks to make sure the user has entered something into the input field. If so, it calls the Web method while passing the information from the input text field that is converted to a number because, as you might remember, data coming directly from a TextInput component will automatically be a string. Finally, we add the listener as an event listener to the Button component.
//create the object to listen to the button component
var clickListen:Object = new Object();
//create the click event for the listener
clickListen.click = function(){
if(number_ti.text.length > 0){
//call the web method
myServiceObject.squareNum(Number(number_ti.text));
}else{
trace(“error”);
}
}
//add the listener to the button component
square_pb.addEventListener(“click”, clickListen);
And the last section creates the function that will collect the results from the Web method and display them in the other text field.
//when the web method receives results back
squareNum_Result = function(result){
results_ti.text=result;
}
If you are not using remoting, and would prefer to use XML, here is the code to use instead of the preceding:
//create the XML object
var myXML:XML = new XML();
//ignore the white space
myXML.ignoreWhite = true;
//create the object to listen to the button component
var clickListen:Object = new Object();
//create the click event for the listener
clickListen.click = function(){
if(number_ti.text.length > 0){
//load the XML
myXML.load(“http://localhost/squareService.asmx/squareNum?
ÂsentNum=”+Number(number_ti.text));
}else{
trace(“error”);
}
}
//add the listener to the button component
square_pb.addEventListener(“click”, clickListen);
//when the XML object receives data
myXML.onLoad = function(){
results_ti.text = this.firstChild.childNodes[0].nodeValue;
}
#include “NetServices.as”
#include “NetDebug.as”
gateway = “http://localhost/flashremoting/gateway.aspx”;
myConn = NetServices.createGatewayConnection(gateway);
service = “http://www.aspxpressway.com/maincontent/webservices/
Âpiglatin.asmx?wsdl”;
myServiceObject = myConn.getService(service, this);
//create the new object
var clickListen:Object = new Object();
//create the event for the listener
clickListen.click=function(){
//get the text
var myString_str:String = input_ta.text;
//call the web method
myServiceObject.toPigLatin(myString_str);
//let the user know something is happening
input_ta.text=”translating . . . “;
//don’t let the user click the button until the method is done
translator_pb.enabled = false;
}
//add the listener to the button
translator_pb.addEventListener(“click”, clickListen);
//collect the results from the web method
toPigLatin_Result=function(result){
//display the results
input_ta.text=result;
//turn the button back on
translator_pb.enabled = true;
}
Much like last time, this code does a lot, so let’s look at it in sections.
The first section gets the necessary external class files and brings them in:
#include “NetServices.as”
#include “NetDebug.as”
The next section initializes the gateway and the service connection with the correct paths:
gateway = “http://localhost/flashremoting/gateway.aspx”;
myConn = NetServices.createGatewayConnection(gateway);
service = “http://www.aspxpressway.com/maincontent/webservices/
Âpiglatin.asmx?wsdl”;
myServiceObject = myConn.getService(service, this);
After that, we create an object to listen to the button-click event. We then add the event callback to the listener. In the event callback, when the button is clicked, a variable is created that holds the information in the TextArea component. We then call the Web method to translate the text while passing the variable with the original text. After that, we place text in the component to show the user something is happening, and then we turn off the ability for the user to click the button again until the results have returned. Next, we add the event listener object to the Button component.
//create the new object
var clickListen:Object = new Object();
//create the event for the listener
clickListen.click=function(){
//get the text
var myString_str:String = input_ta.text;
//call the web method
myServiceObject.toPigLatin(myString_str);
//let the user know something is happening
input_ta.text=”translating . . . “;
//don’t let the user click the button until the method is done
translator_pb.enabled = false;
}
//add the listener to the button
translator_pb.addEventListener(“click”, clickListen);
Finally, we create the results function to collect the translated text coming back. It will display the results in the TextArea component, and turn the button back on to use again.
//collect the results from the web method
toPigLatin_Result=function(result){
//display the results
input_ta.text=result;
//turn the button back on
translator_pb.enabled = true;
}
Now test the movie, place this paragraph in (or one of your own), and click the Translate button. When the results are returned you should see something like Figure 24.8.
And if you are working with XML, replace the preceding code in the actions layer with this:
//create the XML object
var myXML:XML = new XML();
//ignore the white space
myXML.ignoreWhite = true;
//create the path to the web service
var thePath:String = “http://www.aspxpressway.com/maincontent/webservices/
Âpiglatin.asmx/toPigLatin?textToTranslate=”;
//create the new object
var clickListen:Object = new Object();
//create the event for the listener
clickListen.click=function(){
//get the text
var myString_str:String = input_ta.text;
//call the web method
myXML.load(thePath+myString_str);
//let the user know something is happening
input_ta.text=”translating . . . “;
//don’t let the user click the button until the method is done
translator_pb.enabled = false;
}
//add the listener to the button
translator_pb.addEventListener(“click”, clickListen);
//collect the results from the web method
myXML.onLoad=function(){
//display the results
input_ta.text=this.firstChild.childNodes[0].nodeValue;
//turn the button back on
translator_pb.enabled = true;
}


Figure 24.9 The Web Services panel.

Figure 24.10 The Define Web Services dialog box.
Now that you have the three Web services in the dialog box, click OK to return to the Web Services panel, and you should see all three listed there. If you click the plus signs beside them, they will expand to show you all Web methods as well as results and parameters for each one.
This panel is an invaluable tool for working with Web services. You can put your Web service in, and instantly see everything you need to know about it. It also ties into the WebServiceConnector component.
The WebServiceConnector Component
The WebServiceConnector component is designed to easily and quickly connect to Web services on the Web. To use it, simply drag it onto the stage, set the URL for the Web service, and trigger it.
Data from the WebServiceConnector comes back as an object as you will see in the following example.
//create an object to listen for when the WebServiceConnector receives data
var resultListen:Object = new Object();
//create the event for the listener
resultListen.result=function (myResults) {
results_ti.text = myResults.target.results;
}
//add the event listener to the WebServiceConnector
myConnector.addEventListener(“result”, resultListen);
//connect to the web service
myConnector.trigger();
The preceding code creates a listener object for the WebServiceConnector component. It then creates an event callback passing it one parameter, the myResults parameter, which will be the results coming back from the Web service. We then add the event listener to the WebServiceConnector, and finally call the trigger() method, which will activate the WebServiceConnector.
When you test the movie, you will get the same result as before using this Web service. This example just shows how simple it is to connect to Web services using the WebServiceConnector.
But what if it were simpler?
myConnector.trigger();
Now select the WebServiceConnector component, go to the Component Inspector panel (Window, Development Panels, Component Inspector), and select the Binding tab.
Now test the movie again. Again, you get the exact same results as before, but the difference is the only ActionScript in this file is the line that activates the WebServiceConnector component.

Figure 24.11 The Add Binding dialog box used to add data bindings between components for fast development.
Now let’s revisit the squareService Web service we built a while back, but this time we will use the WebServiceConnector component to take out a lot of the hard work. Again, the only code we will need is the code that will activate the connection.
//create the listener object
var clickListen:Object = new Object();
//add the event to the listener
clickListen.click = function(){
myConnector.trigger();
}
//finally add the event listener to the button
square_pb.addEventListener(“click”, clickListen);
The preceding code is nothing new; we create the event listener object. Then we set the event to the listener that will trigger the WebServiceConnector to activate. And finally, we add the event listener to the Button component.
Test the movie, and you will see the same results as before, but this time with very little coding at all.
Using the WebServiceConnector component makes creating Web-service–ready applications quick and easy. Use it to experiment with other Web services.

Figure 24.12 The Bound To dialog box.
Now that you have seen how to absorb Web services created by other people, you might want to start working on some of the major Web services on the Web such as the Amazon.com Web service found at:
http://www.amazon.com/gp/aws/landing.html/002-9580473-9832806
Or possibly you might want to experiment with the Web service API of the mother of all search engines, Google.
Absorbing the Google Web Service
Google is one of the most well-known search engines on the planet, and they have opened up their search engine to the public for free.
With the Google Web service, you can search the Web for anything, and have the results sent back to an application you design and build.
The first thing you will have to do is get your key from Google by signing up at
http://www.google.com/apis/
The key lets Google know who is using the search engine, and you are only allowed 1000 requests per day, but that’s plenty.
When you have gotten your personal key, you will need to download the sample file for this application from the accompanying Web site. The application itself has everything but the key.
The purpose of this application is to see the power of Web services. This example will allow you to search at will, and it will return 10 results each time. When one of those results is selected, it will display a short description of the link. And if you have selected a link, you can launch it into a browser window using the Launch Link button.
When you have downloaded the sample application and have gotten your key, open the file googleSearch.fla and follow these steps to make it work:

Figure 24.13 The Google search application using Web services.
Let’s go over the code in the first frame of the actions layer.
The first section creates the object to listen to the search button. We then assign the event to it that, when triggered, will activate the WebServiceConnector component. It will also clear the description because there is new data coming back. And finally, we add the event listener to the Search button.
//create the search object
var searchListen:Object = new Object();
//create the event for search button listener
searchListen.click=function(){
//trigger the WebServiceConnector
myConnector.trigger();
//clear the description field
description_ta.text = “”;
}
//add the event to the search button
search_pb.addEventListener(“click”, searchListen);
The next section creates another listener object, this time for the List component. When the event is triggered, the description text component will display the information from the actual WebServiceConnector component based on which element was selected. And as before, the event listener is added to the instance of the List component.
//create the listener object for the list component
var listListen:Object = new Object();
//add the event to the listener
listListen.change=function(){
//send a description to the text field
description_ta.text=myConnector.results.resultElements
Â[list_lb.selectedIndex].snippet;
}
//add the listener for the list component
list_lb.addEventListener(“change”, listListen);
The final section again creates another listener object, this time for the Launch button, that will allow users interested in the search results to view the Web page. Then the event is added that will call the getURL() method and place the content in its own browser window. Finally, the event listener is added to the launch button.
//create the object for the launch button
var launchListen:Object = new Object();
//create the event for the listener
launchListen.click=function(){
getURL(list_lb.value,”_blank”);
}
//add the event to the launch button
launch_pb.addEventListener(“click”, launchListen);
This application is not using all the results that are returned. Use the Web Services panel to see what else is available, such as the total number of results as well as the amount of time it took to search for a given topic. The possibilities are endless, and this application is merely a good start.
Summary
This chapter covered a lot of material pertaining to Web services and their integration into Flash. If Web services are the future in middleware, and Flash is the future of application front ends, it’s a perfect match.
Follow the links to other Web services provided earlier in this chapter, and add them to the Web Services panel to see how to use and experiment with them.
Next review:
ActionScript : the Definitive Guide
Previous review:
Review: Actionscript 2.0 Dictionary
Open Source and free Development Tools for Flash
Everyone to their bases - Flash is under attack!
Stay current on what's happening in Flash business. Sign up now for the Flashzine newsletter.