How It Works:
Pretty cool? Now aside from the common data accessing, and Web server control
usage, I'll outline some specifics. By virtue of creating our proxy class
in Step 2 with a namespace, we need to import
it the dll we created in Step 3.
<%@ Import Namespace="WService" %>
We instantiate it or reference our object with:
[C#]
GetInfo supInfo = new GetInfo();
[VB]
Dim supInfo As New WService.GetInfo() |
which is our Web Service class. We then retrieve our dropdown list parameter
and pass is to our ShowSuppliers constructor method like so:
[C#]
string Catg = DropDown1.SelectedItem.Text;
DataSet MyData = supInfo.ShowSuppliers(Catg);
[VB]
Dim Catg As String = DropDown1.SelectedItem.Text
Dim MyData As DataSet = supInfo.ShowSuppliers (Catg) |
And the rest? Just common .NET stuff, which I've assumed the reader to
kind of understand. Nevertheless, it shouldn't be to hard to follow or figure
out. The .NET documentation and Quickstart Tutorials will help will plenty
more information.
Well, guess what? We're completely done!
Step 5 - Show it Off
Congratulations are in order, for you have now built your first full fledged
.NET XML Data Web Service in no time flat, without any IDE program such
a VS.NET I might add, and only using something as simple as Notepad. Now
can anyone really say this was a big, difficult ordeal? I didn't think so.
Additionally, if you're wondering, OK now I have a cool Web service. How
will anyone else "discover" it? Well, exactly, you're right. What?
Yeah, absolutely. Just kidding, with XML Web service "discovery",
you can advertise your Web service and expose its location and other information,
alongside a .discomap file providing links to these files.
XML Web Service discovery or DISCO for
short is Microsoft's Web Services Discovery
tool which "discovers" the URL for a Web Service and saves that
information in a file on your local server.
Here's how:
disco http://localhost/suppliers.asmx?DISCO
This created a static discovery file with a WSDL file with all important
information pertaining to your Web Service, again providing you want to
advertise. Opposite this static discovery file is a dynamic discovery .vsdisco
file which notes all available Web Services located within that URL.
Remember in Step 2, the WSDL command for creating the source file with
"?WSDL"? Now for an already "discovered" file you can
use:
wsdl.exe /l:CS /n:WService /out:bin/GetSuppliers.cs
http://localhost/suppliers.wsdl
to create your source file and in turn, your DLL for Web Service access.
When you examine the created .disco file you'll notice the follwing information,
<contractRef ref="http://localhost/suppliers.asmx?wsdl"
docRef="http://localhost/suppliers.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/"
/>
which contains the link to your Web Service so others could discover it,
alongside XSD schemas, and service descriptions. By this information others
can parse the WSDL document, and build a proxy source file and implement
this Web Service locally!
If you do have something you'd like to share, run over to the Microsoft
UDDI (Universal Description, Discovery and Integration) Business
Registry (UBR) node - http://uddi.microsoft.com/,
which is currently supported by Microsoft, IBM and Ariba. Here you can find
other available Web Services and any details, register your Web Service
or discover more about this whole business.
A Little Asynchronous"ity"
Before, I conclude this article; I need to mention an additional method
of calling Web Services from your application. Web Services by default form
are called synchronously. As a result, both the application and its inherent
Web Service will have to finish simultaneously, whereby one possibly quicker
method within the application will have to wait for the other slower one
to first finish, before the application can fully display its results, potentially
creating an unnecessary delay to the client. Likewise, since Web Service
calls make use of Port 80 for communications, they can at times cause this
type of delay. Therefore, how would one be able to remedy such a situation?
With a little Asynchronous"ity", of course.
There four common ways to make asynchronous method calls. Here we will
demonstrate waiting for our asynchronous call utilizing the WaitHandle method
which determines when the service call is complete. The other three possible
methods for asynchronous calls include:
1) The IsCompleted property of the IAsyncResult returned by BeginInvoke,
within our BeginSuppliers Method
2) Executing a callback method when the asynchronous call finishes
3) Finally, parallel any processing or code until the call completes prior
to calling EndInvoke
So given that Asynchronous calls can perform a given task, without affecting
other functions around them, let's implement our chosen technique. Going
back to Step 2, you'll remember how we created our proxy class file for
our .asmx Web Service file. If you actually took the time to inspect it,
you will have noticed aside from our main ShowSuppliers Dataset function,
two additional functions were listed below it - BeginShowSuppliers
and EndShowSuppliers. These are the Asynchronous
functions that will enable us to produce Asynchronous Web Service calls
implementing the WaitHandle Classes WaitOne() Method, and here's how:
We do all this from our .aspx page we created in Step 4. Here's all the
additional code:
//Instantiate DLL
GetInfo supInfo = new GetInfo();
// Begin the Asynchronous call to ShowSuppliers
IAsyncResult AsyncWS = supInfo.BeginShowSuppliers(Catg, null, null);
//We wait for the callback
AsyncWS.AsyncWaitHandle.WaitOne();
//We return the data bypassing the initial ShowSuppliers Method
DataSet MyData = supInfo.EndShowSuppliers(AsyncWS); |
Notice, just a few more lines of code were added. The only thing that changed
is that we added our asynchronous methods right after we instantiated our
dll. After this is where we create an instance of our IAsyncResult object
that will let us know when the Web Service process has finished.
IAsyncResult AsyncWS = supInfo.BeginShowSuppliers(Catg,
null, null);
Here above, we called the asynchronous BeginShowSuppliers
method that accepts our initial dropdown list parameter and two other mandatory
arguments which, in this example, were not included, and were substituted
with null. The second argument would typically call the ASyncCallBack
object responsible for calling another method once the BeginShowSuppliers
completes, contrary to our example. The third argument would contain information
about the asynchronous operation.
We then next implement the AsyncWaitHandle
that handles and allows us to incorporate different kinds of synchronization
techniques. There are a few AsyncWaitHandles available to us. With the WaitOne
method in our line below, we wait for the WaitHandle to receive a callback
signal. Further available methods include: WaitAll(),
that waits for all elements to receive a callback signal, and WaitAny(),
which waits for any one of the elements to receive a callback signal, both
utilizing specified arrays as one the overloaded element arguments, alongside
an Integer for specific time interval waiting and, or Timespan as well.
In any event, all WaitHandles have multiple overload forms available to
them that can be further viewed in the .NET SDK documentation.
//We wait for the default callback
AsyncWS.AsyncWaitHandle.WaitOne();
Quick digression regarding the line above: Although our WaitOne
method as shown, in default form will work fine, it can be overloaded. In
illustrating, our WaitOne Handler once overridden
in a derived class will block the current thread until the current WaitHandle
receives a signal. The two arguments it allows, paralleling what the other
two Wait methods also accept, are: 1) waiting a set amount of milliseconds
to pass, and 2) a Boolean value, true or false specifying whether to exit
the synchronization domain before the wait.
Once the waiting is over, we return our results via the EndShowSuppliers
method that got the OK from the WaitHandle.
The AsyncWaitHandle method being a resource
releaser, OK'ed our supInfo.EndShowSuppliers
method below, and in turn obtained our data, while the rest of our application
didn't grow impatient.
//We return the data
DataSet MyData = supInfo.EndShowSuppliers(AsyncWS);
Therefore, in coping with the possible speed limitations allotted us via
HTTP network traffic, we can implement our Web Service without any concern
the rest of our application will wait impatiently until all is completed.
With some Asynchronous"ity, our application will run its entire
course, in conjunction with our possibly leisurely Web Service, simply jumping
in when it's finished.
In summing up, our BeginShowSuppliers method
once initialized returns instantly to notify (though not in this case -
we use the WaitHandler) your applicable
callback function that the process is done, and it's OK to call the EndShowSuppliers
method and return the results.
And there you have it, a quick look at Asynchronous Web Services. As you
may have wondered, yes, this can get far more complex than what was just
aforementioned. Nevertheless, with the amount you have learned now, it should
be a little less intimidating.
Conclusion
So, not that bad, huh? Realizing how fast you could create a nice, functional
.NET XML Data Web Service, and even an Asychronous one to boot, should've
put a smile on your face.
Additionally, be sure to explore all the .NET documentation for greater
detail on all presented here for additional tweaking, implementing error
handling, security, caching, and few other things to keep in mind when creating
and consuming Web Services. Even so, there's plenty of stuff in the .NET
documentation and online going into more detail about all this.
Therefore, with all aforementioned, it's really quite easy creating and
consuming your own web services, or discovering and consuming other available
ones over the Internet and utilized them as if those applications reside
on your local server! I tell ya, with each passing moment .NET reveals itself
a more truly amazing and extremely powerful platform.
Until Next Time, Happy .NETing </>