In this chapter, you will learn how to:
Build the credit card validation example that we use throughout this book to demonstrate the development of an XML Web service.
Understand the functionality contained in the CreditCardValidator.dll library that is used in the examples.
Understand the fundamental program elements provided by the Microsoft .NET Framework that are used to create an XML Web service.
The HelloWorld service you developed in Chapter 2, was very simple and provided no useful functionality. Starting in this chapter, we begin developing an XML Web service to perform credit card validation, a service that offers a solution to a real-world need. We will start with a simple solution and build on that foundation in subsequent chapters as we introduce new aspects and features of XML Web service development.
The use of credit cards is a well-understood activity, and using credit cards to pay for goods and services over the Internet is becoming increasingly common. Whenever a credit card is used, checks must be made to ensure its authenticity and determine whether the owner has sufficient credit for the transaction. Internet-based credit card validation is an operation for which an XML Web service offers an excellent solution.
To avoid getting bogged down in the logic associated with credit card validation, we have provided an implementation in the CreditCardValidator dynamic link library, which encapsulates all the logic necessary to support our examples. Instructions for downloading and installing the library are provided in the Introduction to this book. If you followed these instructions, you will find the CreditCardValidator.dll library in the C:XMLWebServicesSBSSamplesCreditCardValidator directory.
The separation of validation (business) logic from the XML Web service implementation allows us to remain focused on the XML Web service aspects of development; this approach is also representative of many real XML Web service development projects in which the business logic is developed separately or already exists from previous projects. In general, we think that separating the underlying business logic from the XML Web service interface that is exposed to the outside world is good practice.
The credit card validation library performs only simple validation of a credit card by ensuring that the card number meets the criteria of the card issuer. This level of validation is sufficient for demonstration purposes, but it does not perform key tasks that are essential for full e-commerce support. Specifically, it does not do any of the following:
Ensure that a credit card number has been issued by a valid provider
Ensure that the credit card has not expired
Ensure that the credit card has not been cancelled by the appropriate card provider
Ensure that the credit card holder has sufficient credit to enter into a transaction
The CreditCardValidator library contains an implementation of the Validator class, which is a member of the XMLWebServicesStepByStep.CreditCardValidator namespace. The Validator class is a stateless thread-safe utility class used to validate credit card numbers. The Validator class contains three public methods, described in the following table. Each method takes a String argument containing a credit card number and returns true or false to indicate whether the number is valid.
Method | Description |
---|---|
ValidateAMEX | Validates that the specified card number is an American Express credit or charge card |
ValidateVisa | Validates that the specified card number is a VISA credit card |
ValidateMasterCard | Validates that the specified card number is a MasterCard credit card |
Each method throws the exceptions listed in the following table if the credit card number passed to the method is incorrectly formatted. Because white space is ignored, spaces between the digits of the credit card number do not cause exceptions.
Exception | Description |
---|---|
CCIllegalCharacterException | Thrown if the credit card number passed to the method contains illegal characters. Only decimal digits (0–9) are valid in credit card numbers |
CCInvalidLengthException | Thrown if the credit card number passed to the method has the wrong number of digits for the type of card |
CCInvalidPrefixException | Thrown if the credit card number passed to the method is not the correct type; for example, if a VISA number is passed to the ValidateAMEX method |
In this chapter, we will use only the Validator.ValidateVisa method; the other methods will be used in later chapters.
If you want to know about the CreditCardValidator.dll library in more detail, Appendix A, contains a full description of its functionality along with source code in both C# and Visual Basic .NET.
To demonstrate the basic features of XML Web services, we will create an XML Web service named VISAValidator, which, as the name implies, is used to validate VISA credit card numbers.
As with all examples in this book, the VISAValidator XML Web service can be developed in either C# or Visual Basic .NET. We provide implementations in both languages as part of the sample code that accompanies this book. For the moment, don’t worry about understanding all of the details. In the following sections, we will explain the meaning of the code statements in the project.
We’ll start by putting the basic project structure in place. The project creation process is discussed in detail in the section "Creating the HelloWorld XML Web Service" of Chapter 2. The VISAValidator XML Web service uses functionality implemented in the CreditCardValidator library, which means we need to add a reference to the library so that Microsoft Visual Studio .NET can resolve references to it during compilation.
Procedure 3-1. Create the VISAValidator Project
Start Visual Studio .NET
Create a new Visual Studio .NET project using either the C# or Microsoft Visual Basic .NET ASP.NET Web Service project template.
In the New Project dialog box, shown here, specify the following URL, at which the new project will be created: http://localhost/XMLWebServices/Chapter03/VisaValidator
Procedure 3-2. Add a Reference to the CreditCardValidator library
Right-click on the References folder in Solution Explorer and select Add Reference from the shortcut menu.
Click the Browse button in the Add Reference dialog box.
In the Select Component dialog box, navigate to the directory where the CreditCardValidator.dll library is located; it will be in the SamplesCreditCardValidator subdirectory of the location where you stored the sample code.
Select the CreditCardValidator.dll file, and then click Open.
You will return to the Add Reference dialog box and can see that the Selected Components list now contains an entry for the CreditCardValidator.dll, as shown here:
Click OK.
On the Solution Explorer toolbar, click the Show All Files button to reveal the project’s hidden files and directories.
Expand the bin folder. You’ll see that it contains a copy of CreditCardValidator.dll.
Procedure 3-3. Implement the VISA Card Validation Functionality
Select Service1.asmx in Solution Explorer. Press F2, or right-click on the file name and select Rename from the shortcut menu. Rename Service1.asmx Validation.asmx.
The default name of Service1.asmx is not descriptive enough and could cause confusion when developing client applications that consume the XML Web service. Visual Studio .NET automatically renames the code-behind file and the resource file associated with the .asmx file, which you can see in the following screenshot.
In Solution Explorer, right-click Validation.asmx and select View Code from the shortcut menu.
This opens the code-behind file, either Validation.asmx.cs or Validation.asmx.vb depending on the language you are using.
Ignore the rest of the template-generated code, but locate and delete the commented out HelloWorld method that we used in Chapter 2. We do not need it and it clutters up our code. Make sure you delete the following lines.
Example 3-1. C#
// 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"; // }
Example 3-2. Visual Basic.NET
‘ 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
Add the appropriate statement to the top of the file to import the XMLWebServicesStepByStep.CreditCardValidator namespace. The implementation of this namespace is contained in the CreditCardValidator.dll library that we added a reference to earlier.
The C# project template imports more namespaces by default than the Visual Basic .NET project template; most of these namespaces are currently superfluous, so you can ignore them for now. After adding the new import statement, the full list of imports should appear as follows.
Locate the Service1 class declaration. We need to change its name to CreditCardValidator and apply the WebService attribute to it. The Visual Basic .NET project template supplies a default WebService attribute that must be replaced. Change the Service1 class declaration to appear as follows.
If you are using C#, because we changed the name of the Service1 class to CreditCardValidator, we must also change the constructor name; this is not necessary in Visual Basic .NET. For C# projects, change the Service1 constructor declaration to the following.
public CreditCardValidator ()
Add the ValidateVISACard method as a member of the CreditCardValidator class.
The ValidateVISACard method has public accessibility and is annotated with the WebMethod attribute, making it available to XML Web service consumers. When invoked, the ValidateVISACard method instantiates a Validator object (implemented in the CreditCardValidator.dll library) and calls the Validator.ValidateVisa method to validate the supplied VISA card number. The Boolean result is returned to the caller. As described in the code comments, the Validator.ValidateVisa method can throw an exception if the VISA card number is incorrectly formatted. We will ignore the exceptions for now, saving a discussion of them until Chapter 7.
Example 3-7. C#
[WebMethod(Description="Validate a VISA card number.")] public bool ValidateVISACard(string p_card_number) { try { return new Validator().ValidateVisa(p_card_number); } catch (System.ApplicationException) { // although the ValidateVisa method in the Validator // class throws exceptions, we will ignore them // for now. return false; } }
Example 3-8. Visual Basic .NET
<WebMethod(Description:="Validate a VISA card number.")> _ Public Function _ ValidateVISACard(ByVal p_card_number As String) _ As Boolean Try Return New Validator().ValidateVisa(p_card_number) Catch x_ex As System.ApplicationException ‘ although the ValidateVisa method in the Validator ‘ class throws exceptions, we will ignore them for now. Return False End Try End Function
The final step is to build the project. Select Build Solution from the Build menu or press Ctrl+Shift+B. We will test our new XML Web service later in this chapter, after we have provided more detail on the XML Web service you just created.
As we did with the HelloWorld example in Chapter 2, we can use Internet Explorer to inspect and test the VISAValidator XML Web service. This testing allows us to look at the operations available through the service, review the format of request and response messages for each operation, and, more important, check that each operation works.
Procedure 3-4. Load the VISAValidator Service Help Page
With the VisaValidator project open in Visual Studio .NET, press F5.
Internet Explorer is launched and loads the Validation.asmx file from the VisaValidator project. You will see the service help page for the VISAValidator XML Web service, as shown here.
The page structure for VISAValidator is similar to that of the HelloWorld example, but if you compare them, you will notice the following differences that result from the changes we made to the VISAValidator code.
The name of the XML Web service and the title of the page are VISAValidator. This is the name we specified in the Name property of the WebService attribute applied to the CreditCardValidator class. By default, the name of the class to which the WebService attribute is applied (CreditCardValidator) would have been used, as was the case with the HelloWorld example.
A description of the VISAValidator XML Web service appears at the top of the page immediately below the service name. We specified this description using the Description property of the WebService attribute that was applied to the CreditCardValidator class.
The link to the ValidateVISACard method is followed immediately by its description. We specified this information using the Description property of the WebMethod attribute applied to the CreditCardValidator.ValidateVISACard method.
The warnings about the use of default XML namespaces that you can see on the HelloWorld page are no longer present. These warnings are absent because we specified our own namespace using the Namespace property of the WebService attribute applied to the CreditCardValidator class.
Click the Service Description link.
Clicking this link displays the Web Services Description Language (WSDL) contract for the VISAValidator service, but we will not go into the details of the content.
Procedure 3-5. Test the ValidateVISACard Web Method
Click the ValidateVISACard link on the VISAValidator service help page. This link takes you to a page, shown here, where you can test the ValidateVISACard operation.
At the top of the page, below the operation name and description, is a Test section. The Test section consists of a simple form containing a text field named p_card_number and an Invoke button. When we tested the HelloWorld example, there was only an Invoke button, no text fields, because the HelloWorld method did not require any input arguments. When testing an XML Web service operation that takes arguments, a form is automatically generated with a text field for each parameter. Note that no type checking is performed at the client end before the arguments are sent to the XML Web service.
To test the ValidateVISACard operation, type a VISA card number into the p_card_number text field and click the Invoke button.
Because the HTTP-GET protocol is used to submit the request to the VISAValidator service, the response is not a Simple Object Access Protocol (SOAP) message, but it is XML. For example, if you type in the invalid card number 1234567890, the response would be
<?xml version="1.0" encoding="utf-8" ?> <boolean xmlns="http://mycompany.com/webservices/">false</boolean>
Below the Test section are three further sections named SOAP, HTTP-GET, and HTTP-POST. As with the HelloWorld example, these sections contain the request and response message formats for each of the three protocols. Although we will not describe the content of these messages, it is interesting to compare the messages for the HelloWorld and ValidateVISACard operations and look at the effect the use of input parameters has on the message structure.
If you have followed the instructions to create the VISAValidator service, the code file for the VISAValidator project should contain the statements shown below. In this section, we will list and explain the most important statements and attributes that were created.
Example 3-9. C#
using System.Web.Services; // the following statement allows the // credit card library to be used using XMLWebServicesStepByStep.CreditCardValidator; [WebService(Namespace="http://mycompany.com/webservices/", Name="VISAValidator", Description="A service to validate VISA card numbers.")] public class CreditCardValidator: System.Web.Services.WebService { [WebMethod(Description="Validate a VISA card number.")] public bool ValidateVISACard(string p_card_number) { try { return new Validator().ValidateVisa(p_card_number); } catch (System.ApplicationException) { // although the ValidateVisa method in the Validator // class throws exceptions, we will ignore them // for now. return false; } } }
Example 3-10. Visual Basic .NET
Imports System.Web.Services ‘ the following statement allows the ‘ credit card library to be used Imports XMLWebServicesStepByStep.CreditCardValidator <WebService(Namespace:="http://mycompany.com/webservices/", _ Name:="VISAValidator", _ Description:="A service to validate VISA card numbers.")> _ Public Class CreditCardValidator Inherits System.Web.Services.WebService <WebMethod(Description:="Validate a VISA card number.")> _ Public Function _ ValidateVISACard(ByVal p_card_number As String) _ As Boolean Try Return New Validator().ValidateVisa(p_card_number) Catch x_ex As System.ApplicationException ‘ although the ValidateVisa method in the Validator ‘ class throws exceptions, we will ignore them ‘ for now. Return False End Try End Function End Class
The first line of both the C# and Visual Basic .NET examples tell the compiler to make the classes in the System.Web.Services namespace available to the application code.
The System.Web.Services namespace contains important .NET Framework functionality that’s required for developing XML Web services. This functionality includes
The WebService class
The WebService attribute
The WebMethod attribute
We discuss each of these elements in the following sections.
When Visual Studio .NET creates a new source file for an XML Web service project, the class that is created is automatically derived from the System.Web.Services.WebService base class. The following statements from the previous listings show the derivation
Example 3-14. Visual Basic .NET
Public Class CreditCardValidator Inherits System.Web.Services.WebService
XML Web service classes do not have to inherit from WebService, but they gain significant advantages by doing so. The WebService class makes ASP.NET intrinsic services available to your XML Web service. ASP.NET intrinsic services are a group of features that allow you to build complex XML Web services by exploiting some of the advanced features of ASP.NET. We explain some of these features in later chapters. For the moment, it is important to know that while XML Web services can be created without using the WebService class, doing so limits the kind of service that can be created. We recommend that you always inherit from this class and all of the examples in this book do so.
The WebService attribute is applied to class declarations. Although it is not mandatory, it does allow you to specify some important configuration parameters for the XML Web service. The most important of these parameters is the namespace.
Visual Basic .NET requires an attribute to be placed on the same line as the declaration of the method or class to which it applies. For clarity, we use the continuation character (_) to break up Visual Basic .NET statements. C# requires an attribute to be placed immediately before the target method or class declaration, but it can be separated by any amount of white space, which is ignored by the compiler.
Here are excerpts from the code that demonstrate the use of the WebService attribute and each of its properties. The table that follows describes the attribute’s properties.
Example 3-15. C#
[WebService(Namespace="http://mycompany.com/webservices/", Name="VISAValidator", Description="A service to validate VISA card numbers.")] public class CreditCardValidator: System.Web.Services.WebService {
Example 3-16. Visual Basic.NET
<WebService(Namespace:="http://mycompany.com/webservices/", _ Name:="VISAValidator", _ Description:="A service to validate VISA card numbers.")> _ Public Class CreditCardValidator Inherits System.Web.Services.WebService
Property | Description |
---|---|
Description | A descriptive message for the XML Web service. The Description property is for the benefit of a human user when viewing information about the XML Web service. |
Name | The name of the XML Web service. The Name property is included in the WSDL description of the XML Web service and is used by consumers to target the service for communications. The default value for Name is the name of the class that is annotated with the WebService attribute. |
Namespace | The XML namespace for the XML Web service. If you do not specify a value for the Namespace property, the default URI of http://tempuri.org/ is used. It doesn’t matter which namespace you use during testing, but you should change the default namespace before making your XML Web service publicly available. You must use a URI that no one else would use to ensure naming conflicts do not occur between your XML Web service and one developed by someone else. It is common to use the Internet domain name of your company as the base of the URI. |
The WebMethod attribute is used to indicate which methods of a class will be included in the interface that your XML Web service exposes to consumers. Each method that you want to make available must be annotated with the WebMethod attribute and must be declared to have public accessibility. It is important to understand that not all methods in a class need to be exposed as part of the XML Web service. The following statements from the listing at the start of this section illustrate the use of the WebMethod attribute.
Example 3-17. C#
[WebMethod(Description="Validate a VISA card number.")] public bool ValidateVISACard(string p_card_number) {
Example 3-18. Visual Basic .NET
<WebMethod(Description:="Validate a VISA card number.")> _ Public Function _ ValidateVISACard(ByVal p_card_number As String) _ As Boolean
In addition to applying the WebMethod attribute, you must be sure that any method that you want to expose as part of an XML Web service is declared with public accessibility. Methods that are not publicly accessible will not be made available to consumers, even if the WebMethod attribute has been correctly applied.
WebMethod defines a series of optional properties that can be used to customize the way that a method is treated and the capabilities available within the context of the method. The following table describes these properties.
Property | Description |
---|---|
BufferResponse | Controls whether the response to a client request is buffered until complete and then sent or is sent as it is serialized. |
CacheDuration | Sets the number of seconds a response to a client request should be held in the cache in order to serve future client requests. Use of the CacheDuration property is discussed in Chapter 12. |
Description | Provides an informative description of the XML Web service method. This description is aimed at people observing the method as opposed to other applications consuming it. We used the Description property earlier in this chapter. |
EnableSession | Determines whether session state is enabled for an XML Web service method. Use of the EnableSession property is discussed in Chapter 10. |
MessageName | Allows you to associate an alias with the XML Web service method name. The alias name is published in the WSDL contract and is the name used by consumers when they communicate with the service. MessageName is used when a class contains overloaded methods. XML Web services do not support overloaded methods, so each method must be given a unique name using the MessageName property. |
You cannot expose overloaded methods (methods with the same name but different sets of parameters) as part of an XML Web service interface. If you want to expose overloaded methods from your class, you must give each method a unique name using the MessageName property of the WebMethod attribute.
To | Do This |
---|---|
Validate a credit card using the CreditCardValidator.dll library | Instantiate the Validator class from the XMLWebServicesStepByStep.CreditCardValidator namespace, and then call whichever of the ValidateVisa, ValidateAMEX, or ValidateMasterCard methods is appropriate. |
Define a class that provides XML Web service functionality | No action is necessary, although applying the System.Web.Services.WebService attribute to the class and deriving the class from the System.Web.Services.WebService class provide access to useful capabilities. |
Define a method that is made available through an XML Web service | Apply the System.Web.Services.WebMethod attribute to the method. |
Set the XML namespace for an XML Web service | Use the Namespace property of the System.Web.Services.WebService attribute. |
18.119.111.70