Creating Web Services

With Visual Studio .NET, creating Web Services couldn't be easier. A Web Service Wizard is available to make the entire process simple. All you need to do is create a new project (VB, C#, or C++), select Web Service (for VB and C#, this will be labeled ASP.NET Web Service), enter a project name, and create the service with the OK button. Figure 14.4 shows the Wizard dialog box as it appears.

Figure 14.4. Visual Studio .NET Offers a Wizard for Web Service Creation.

graphics/14fig04.jpg

The Wizard creates a simple method for you named HelloWorld(). It's commented out, but it can easily be used by removing the // characters at the beginning of each line of the HelloWorld() method. This gives you a good idea of how to structure Web methods. Below is the code that the Wizard adds to C# projects:

 // WEB SERVICE EXAMPLE // The HelloWorld() example service returns the string Hello World // To build, uncomment the following lines then save and build the // project // To test this web service, press F5 //        [WebMethod] //        public string HelloWorld() //        { //            return "Hello World"; //        } 

I'll point out several things about the HelloWorld() method. First, it is decorated with a [WebMethod] attribute. This takes care of the communications details for you. Actually, there is a great deal of code that this injects into your compiled program on your behalf. All of the SOAP conversion code, all of the communication code, and other boiler plate methods are injected by simply adding the [WebMethod] attribute. Not all of your methods need this attribute only the ones that must be discoverable by the discovery process.

You need to notice that the HelloWorld() method is marked as public. WebMethods that are not marked public cannot be discovered via the discovery process, and, more importantly, they can't be called. Make sure that methods that must be discovered and accessed have the [WebMethod] attribute and are marked public.

This method returns a string object. WebMethods can return just about any kind of object you want. There are a few exceptions, such as SqlReader objects, but the exceptions are few.

The method can also take just about any kind of objects as arguments, too. The HelloWorld() method takes no arguments, but Web Services that we'll create later on will take arguments.

As you would imagine, Visual Basic Web Services look slightly different from C# Web Services. The VB version of the sample HelloWorld() method can be seen below. Note that VB attributes look a little different from C# attributes. The attribute you can see is in the form <WebMethod()>.

 ' WEB SERVICE EXAMPLE ' The HelloWorld() example service returns the string Hello World. ' To build, uncomment the following lines then save and build the project. ' To test this web service, ensure that the .asmx file is the start page ' and press F5. ' '<WebMethod()> Public Function HelloWorld() As String '  HelloWorld = "Hello World" ' End Function    ' WEB SERVICE EXAMPLE ' The HelloWorld() example service returns the string Hello World. ' To build, uncomment the following lines then save and build the ' project. ' To test this web service, ensure that the .asmx file is the start page ' and press F5. ' 

Sales Commission Web Service

As an example, I've created a Web Service that calculates sales commissions. Many companies will encapsulate functionality such as sales commissions in Web Services because it offers a single point to which all applications can go to perform the task. If, for any reason, the logic needs to be updated, there is only one place that it must be updated. All applications that use the Web Service won't be affected functionally.

WEB CONTENT: The complete code for this application can be found via links from www.ASPNET-Solutions.com/chapter_14.htm. There are two versions, one for C# and one for VB. You can also access the Web Service from your client application at the URL http://www.ASPNET-Solutions.com/SalesCommission/service1.asmx?WSDL.

There is an application that demonstrates using this Web Service, and it can be run from a link on the same page.


When I think about what Web Services have to offer, it reminds me of what COM offered. You get a way to reuse components, along with a way to maintain contacts with previous applications.

The sales commission Web Service takes the name of a salesperson, and returns her rate of commission. To keep this first example clear, it doesn't do any database access. The values are hard-coded into an array. A production implementation will obviously keep the values in a database.

All of the code (with the exception of one method that we'll talk about later) can be seen in Listing 14.9. An array named dCommissionRates contains the rates for the salespeople. There are only four in the list, thus only four values. The first value (at index 0), actually is 1. This value will be returned in case a salesperson's name can't be found.

The callable WebMethod is named GetCommissionRate(). It takes a single string argument containing the sales person's name. It returns a double representing the rate (in percent) of commission. The GetCommissionRate() method simply calls the GetSalesPerson() method to get an index representing the person's position in a list. If the value returned is 1, the name wasn't found.

The GetSalesPersonIndex() method gets a list of all sales people from the GetSalesForceList() method. The contents of this list are then compared to the name that was passed into the GetCommissionRate() method. When a match is found, the index is returned.

Listing 14.9 This Is the Code for the SalesCommission Web Service.
 static double[] dCommissionRates = {     -1.0, 5.0, 6.2, 4.8, 9.3 }; [WebMethod] public double GetCommissionRate( string strName ) {     int nIndexOfName = GetSalesPersonIndex( strName.ToUpper() );     return( dCommissionRates[nIndexOfName+1] ); } int GetSalesPersonIndex( string strName ) {     StringCollection SalesForceList = GetSalesForceList();     for( int i=0; i<SalesForceList.Count; i++ )     {         if( strName == SalesForceList[i].ToUpper() )         {             return( i );         }     }     return( -1 ); } StringCollection GetSalesForceList() {     StringCollection SalesForceList = new StringCollection();     string[] Names = {"John Doe", "Sally Schmoh",         "Jim Smith", "Suzy Miller"};     SalesForceList.AddRange( Names );     return( SalesForceList ); } 

Once Web Services are compiled in Visual Studio .NET, they can be executed. This is possible even though Web Services can't execute directly and have no user interface. Visual Studio .NET creates an interface page for you that makes it easy to call the Web Service methods. This page appears when you execute the Web Service, and any public method that has the [WebMethod] attribute will show up in a list of methods that can be called, as you can see in Figure 14.5.

Figure 14.5. Public Methods That Have a [WebMethod] Attribute Show Up for Public Consumption.

graphics/14fig05.jpg

When methods are invoked, a page appears into which you can supply parameters. Each parameter that is required will have a text box into which the parameter value can be entered, as shown in Figure 14.6.

Figure 14.6. When a Method Is Invoked That Requires Parameters, You'll Get a User Interface with Which You Can Supply the Parameters.

graphics/14fig06.jpg

Web Services natively exchange data as XML. For this reason, when you click the Invoke button to call into the method, the result is shown as XML data. By typing in John Doe, we should get the commission rate of 5 as a return value. The following XML shows the XML that results from this Web Service when the salesperson John Doe has been entered and the commission rate of 5 is returned:

 <?xml version="1.0" encoding="utf-8" ?> <double xmlns="http://tempuri.org/">5</double> 

There's one other thing that would be important for applications that use this Web Service. That is the capability to get a list of salespeople. Client applications could populate selection boxes so that the names wouldn't have to be typed in manually. Returning a StringCollection object does the trick, as you can see for the GetSalesForce() method below. This method is public and marked with a [WebMethod] attribute, so it is discoverable.

 [WebMethod] StringCollection GetSalesForce() {     return( GetSalesForceList() ); } 

The GetSalesForce() method returns the StringCollection object as a sequence of strings. The XML that the GetSalesForce() method returns can be seen below:

 <?xml version="1.0" encoding="utf-8"?> <ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/">   <string>John Doe</string>   <string>Sally Schmoh</string>   <string>Jim Smith</string>   <string>Suzy Miller</string> </ArrayOfString> 

Pharmacy Web Service

I have a background in pharmaceutical software. One of the most essential pieces information that pharmaceutical applications need is information relating to a given pharmaceutical item. Drugs are uniquely identified by a National Drug Code (NDC) number. Given this number, all information about a drug can be obtained.

WEB CONTENT: The complete code for this application can be found via links from www.ASPNET-Solutions.com/chapter_14.htm. There are two versions, one for C# and one for VB. You can also access the Web Service from your client application at the URL http://www.ASPNET-Solutions.com/PharmFromNDC/service1.asmx?WSDL.

There is an application that demonstrates using this Web Service, and it can be run from a link on the same page.


Only one method comprises this Web Service. It is named GetPharm(), and it can be seen in Listing 14.10. It receives a single string parameter that contains the NDC number of a drug. It then returns a string containing the name, strength, and dosage form for the drug.

The first thing the method does is create a SqlConnection object. This takes care of the database connection functionality. An application variable named Application["DBConnnectString"] is initialized in Global.asax and has the complete connection string.

There's a try/catch block so that exceptions can be handled. Inside the try, the SqlConnection object (which is named myConnection) is opened. A SqlCommand object is created next, and it is created with a SQL string that selects information from the DrugList table. The following is an example of the SQL that might be formed from an NDC number:

 select * from DrugList where NDC=' 1238000021' 

The command object is executed so that a recordset will be returned. The method that's called is ExecuteReader(), which returns a SqlReader object. The SqlReader object is a read-only, forward-only recordset. And this is perfect for what we need because we're simply going to look for a matching record.

If there is a matching record, the reader.Read() method will return true. Then the column data can be used to create the return value string. Care must be take to check for null columns since the DrugList table allows some fields to be null. The IsDBNull() method is what's used here to check for null values. If the data for any column is null, no action is taken. Otherwise, the information is concatenated onto the return string.

The SqlReader and SqlConnection objects are closed, and the string data is returned. In the case of an exception, the exception message is returned.

Listing 14.10 This Is the Code for the PharmFromNDC Web Service.
  [WebMethod] public string GetPharm( string strNDC ) {   // Create the connection object.   SqlConnection myConnection =     new SqlConnection( Convert.ToString( Application["DBConnectString"] ) );   try   {     // Open the connection.     myConnection.Open();     // Create the command with the SQL.     SqlCommand myCommand = new SqlCommand(       "select * from DrugList where NDC='" +       strNDC + "'", myConnection );     // Execute and get a recordset.     SqlDataReader reader = myCommand.ExecuteReader();     string strReturnData = "Error: No Matching Record";     // Check the data for name and other information.     if( reader.Read() )     {       strReturnData = reader["Name"].ToString();       if( !reader.IsDBNull( 4 ) )       {         strReturnData += ( " " + reader.GetString( 4 ) );       }       if( !reader.IsDBNull( 5 ) )       {         strReturnData += ( " " + reader.GetString( 5 ) );       }       if( !reader.IsDBNull( 6 ) )       {         strReturnData += ( " " + reader.GetString( 6 ) );       }     }     reader.Close();     return( strReturnData );   }   catch( Exception ex )   {     return( "Error: " + ex.Message.ToString() );   }   finally   {     if( myConnection.State == ConnectionState.Open )     {       myConnection.Close();     }   } } 

This Web Service can be tested from within Visual Studio .NET. When invoked with a valid NDC number, the returned XML will contain information for the pharmaceutical product that matches the NDC number. The NDC 1238000021 returned the following XML:

 <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://tempuri.org/">NITROUS OXIDE 99.5 % GAS</string> 


ASP. NET Solutions - 24 Case Studies. Best Practices for Developers
ASP. NET Solutions - 24 Case Studies. Best Practices for Developers
ISBN: 321159659
EAN: N/A
Year: 2003
Pages: 175

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