Using ASP.NET/WebServices For UPS Shipping QuotesBy Dan Anderson
I like to experiment with new technology, to the point where I have crashed my machine more times than I can remember! But probably the most exciting new technology for me has to be the new .NET framework from Microsoft. (If you are unfamiliar with ASP.NET, the ASP side of the .NET framework, be sure to check out the ASP.NET Article Index!) With so many new capabilities, the possibilities for developers are limited only to the imagination (this IS, of course, my own humble opinion). After reading an article from Richard Lowe entitled Using Microsoft's XMLHTTP Object To Get Data From Other Web Pages, I decided to see how his example could be suited to fit the .NET framework using Web Services.
So, if you're new to ASP.NET, you might be asking what Web Services are, exactly. In short, they are pieces of program logic that are programmatically available via the Internet. Basically, you can author a web service and make its properties and methods available to other developers across the web without writing vast amounts of documentation for an API or distributing DLLs to everyone who wishes to use them. With Web Services, a developer could include functionality from another server into their own code quite easily.
Perhaps one of the coolest features of Web Services is that they can be modified, re-compiled, and made
available "on the fly." That means you don't have to stop the web server; that means you don't have to use
regsvr32.exe, or interrupt existing calls to the old code!
Calls to a Web Service will complete their execution under the old code, while new requests to the web service
are handled with the new code, seamlessly. What a deal, eh?
So how do you make use of Web Services? Web services are written as
.asmx files and compiled
through a supplied application (
WebServiceUtil.exe) to create the final web service DLL.
(Of course you will need to have the .NET Framework SDK installed... learn more on how to do this at:
Part of this process includes generating SDL (Service Definition Language), which is, essentially, a SOAP
description of how the web service works, what parameters are required (including their data types), and
return parameters. You can view the SDL output of a web service simply by typing in the full URL of the web
service and adding
?SDL to the end of it. For example, the SDL output of our
example in this article, using
http://localhost/asp2/ups.asmx?SDL as the URL, can be seen
on the right.
Using this SDL contract, as it is called, the next version of Visual Studio will read all of the properties and methods of the web service and make them available programmatically to the developer. Pretty neat, eh?
In Richard Lowe's articles, he explains how to use Microsoft's XMLHTTP object to retrieve shipping rate quotes from UPS for packages without visiting the UPS site. After experimenting with his code, I decided to port it to the .NET architecture as a web service because it could prove extremely useful as a tool for understanding how web services will simplify the life of developers.
For this article I created a Web Service called "UPS" (not much imagination, eh?), which we will walk through one step at a time. The complete code is a bit lengthy, so you can view it here in its entirity if you'd like. Now, let's walk through the code!
This line says that we are writing a web service, using Visual Basic as the language, and assigning it a
class name of
UPS. Class names are important, because they define wrappers for various pieces
The next several lines, each of which begins with the word
Imports define the libraries that our
web service will require at compilation time in order to include tools required for the web service. In this
instance, the two most important ones are
make the HTTP-POST and HTTP-GET functionality available. We also include
because we are using string manipulation routines and other VB-specific calls within the code.
Next, we declare the class name again, wrapping it around the functionality of the web service. Now we're
ready to add our functionality. We declare a public function titled
GetPrice, but you will note
that we preceded the name of the function itself with a
WebMethod() statement. This tells the
compiler that the function itself is available via the web. Any function or subroutine which does not include
this directive is not accessible from the web, or in other words is not "web-callable".
GetPrice function requires a number of parameters in order to obtain rate quotes. We will
not go into an explanation of these parameters. Instead, you can find out more by going to
UPS.com and clicking on the "E-Commerce" link.
Next, we declare several object variables:
WebReq object variable will be used to hold the request being sent to UPS, while
WebResp will hold the response from the UPS server.
StrStream is a stream object
used to stream the response received into a variable.
URLRequest will hold the constructed
string to be sent to UPS.
We next call a private function included in the web service called
BuildUPSRequest, which builds
the querystring from the variables passed in to the
GetPrice function. This string is then used
with the next line:
This directive creates an instance of the
WebRequest object using the
object, which creates an HTTP request to the specified URL. By default,
requests using the GET method, although you can override that setting through code.
Next, we read the response from the URL called using the following code:
The first line retrieves the response from the URL using the
GetResponse() directive of the
WebRequest object, while the second line assigns the output of the response to a stream object.
Note that the last directive in the line states
System.Text.Encoding.ASCII, which means that we
want the returned data encoded as ASCII character text. There are a number of other encoding schemes available,
but that is another topic altogether.
Now, we get to use the new
Try...Catch mechanism of Visual Basic, which allows us to manage
errors more gracefully. In the
Try portion of the code, we are reading the returned data in the
Stream object a line at a time, looking for the line which contains the relevant portion of data returned by
UPS. The line that has this data begins with
upsonline, and all of the information regarding the
shipping rates in included in that same line, delimited with percent signs. So, we will ignore everything that
does not begin with
upsonline. Once we have found that line, we use the VB Split function to put
the data into an array, which is defined by the line
Dim strArrayData() As String. This defines
the array as an array of strings.
We check the fourth member of the new array, the first four digits of which indicate success or failure of the request. If the first four digits are not equal to zeros, UPS has returned an error to us. So, we put the error string value into the return parameter of the function and exit the process. Otherwise, if the return code is equal to zeros, the data was successfully retrieved from UPS. The shipping rate in that case would be contained in the thirteenth member of the array, which is then placed in the return parameter of the function.
Catch portion of the code simply says to put the error code into the return parameter of the
function. You could expand on this by writing the error to the Windows Event Log (yes, you can now do this
easily in .NET!), but we kept it simple in this example. (In case you're interested in learning how to
write to the Event Log with ASP.NET, check out: Writing to the
Event Log with ASP.NET!)
That pretty much ends the description of the Web Service file. Now that we have our Web Service, we need an easy way to call it from an ASP.NET page. We'll look at how to accomplish this in Part 2!