|
Spring is almost here, and it's time to
create .NET stuff! So, building on my article of last year, "Build
a Custom Stock Quote Component", I decided it would be a fun
exercise to "stretch my skills" a bit and build a new one, but
this time -- to do it in C# as a full-fledged .NET WebService. And, since
Microsoft has been nice enough to give away a WebService Behavior HTC
that can be "plugged in" to a DHTML web page to act as a webservice
consumer, I thought that would be an elegant finishing touch to show an
example of building a consumer Web page for my new StockQuote class. We'll
deal with getting the WebService built and running in this installment,
and in Part II, we review how to use the WebService DHTML Behavior in
a regular client-side .htm page to consume the WebService. (The downloadable
code link at the bottom of this article, however, contains ALL the code,
'cause I know how you hate to wait for people's "multiple part' articles!)
In Part II, I'll get into some neat client-side stuff, so visit often.
On a side note, If you're in a quandary
about DOT NET and you aren't sure whether to stay with VB6 or go to VB7
or start with C#, my advice is -- after a great deal of agonizing study
and thought -- conserve all the extra time you can find, DROP EVERYTHING,
and get started with C#. Forget VBScript (its already a dinosaur) as well
as VB6 and even Javascript. Microsoft has over a million lines of C# code
in the .NET platform - those guys are eating, breathing, sleeping and
everything else in C#. And unlike their brethren at Oracle and Sun, they've
submitted it to the ECMA for certification. In sum, C# is an elegant,
simple, and powerful programming language that you're almost certain to
see on other platforms while the Java guys who are still too busy bashing
the guys in Redmond to see what's comin' at-em on the turnpike at 100
miles an hour will likely be wondering what happened.
In this article, we're going to walk through
the Webservice C# code first, and then we'll take a look at the DHTML
page and how the WebService Behavior can be used to easily wire up the
page to act as a webservice consumer.
While this is a pretty simple class with
only one method, "GetQuote" it still demonstrates some important
techniques- handling and parsing multiple stock symbols as input parameters,
utilizing the WebRequestFactory class, as well as the StreamReader and
StringBuilder .NET classes to parse and clean up the response stream and
process the return values.
Finally , we'll build a valid XML return
document that the WebService returns to the calling client, as well some
simple error -handling code.
If you don't have the full .NET Beta 1
Visual Sudio release, that's OK - you can build this stuff in Notepad
and compile and run it just fine, as long as you've downloaded and installed
the .NET Framework SDK. I prefer the Visual Studio IDE for
the Intellisense and all the cool access to servers, services, databases,
and even Webservices (wherever in the world they may reside) which all
get "wired up live" right into your IDE and can be brought in
to one central location at your fingertips. But sometimes it's nice
to just whip out NotePad or EditPlus and start codin' (kind of like when
your Commodore 64 used to come up with the blue screen saying "38632
BASIC BYTES FREE"-- man those were the days...).
First we need to start a new .asmx file
because that's what tells the CLR (Common Language Runtime) that this
is a Webservice. We start out by declaring our PageLanguage and starting
class name, along with the CLR references that we'll need for the webservice:
<%@
WebService Language="C#" class="StockQuote" %>
using System ;
using System.Web.Services ;
using System.Net ;
using System.IO ;
using System.Text ;
Next
we declare our public class "StockQuote" as a webservice, with
the [WebMethod] directive:
public
class StockQuote : WebService
{
[WebMethod]
Then
we declare our public function and set up some required variables, along
with the beginning of our try-catch block:
public
string GetQuote(string symbol)
{
string result =null;
try
{
//URL to Yahoo spreadsheet format stock quote server...
string serverURL =@"http://quote.yahoo.com/d/quotes.csv?s="+symbol+"&f=sl1d1t1c1ohgvj1pp2owern&e=.csv";
char[] delim = {' '} ;
char[] delim2 = {','};
string[] symbols = symbol.Split(delim) ;
string sTemp=@"";
string sContentTemp=@"";
string sContentNew=@"";
string strChar="";
We
then create a HttpWebRequest object for the stock URL:
HttpWebRequest
webreq = (HttpWebRequest)WebRequestFactory.Create(serverURL);
-- and Retrieve HttpWebResponse object from the stock URL using the StreamReader
object:
HttpWebResponse
webresp = (HttpWebResponse)webreq.GetResponse();
StreamReader strm = new StreamReader(webresp.GetResponseStream(), Encoding.ASCII);
We then loop through each line from the
stream, building our return XML Document string, but first we also "clean
out" some of Yahoo's "noise" (quote) characters using the
StringBuilder class:
StringBuilder
strContent = new StringBuilder("");
sTemp+="<StockQuotes>";
for(int i=0;i<=symbols.GetLength(0)-1;i++){
sContentTemp = strm.ReadLine();
strContent.Append(sContentTemp);
for (int k=0;k<=strContent.Length-1;k++){
// remove the char from StringBuilder string if contains quite symbol
( \" )
if(strContent[k].ToString()=="\"" )
strContent.Remove(k,1);
}
// now should have clean string, create array of elements
string[] contents=strContent.ToString().Split(delim2);
// Clear out our StringBuilder for next iteration
strContent.Remove(0,strContent.Length);
sTemp+="<Stock>";
sTemp+="<Symbol>" +contents[0]+"</Symbol>";
sTemp+="<Last>" +contents[1]+"</Last>";
sTemp+="<Date>"+contents[2]+"</Date>";
sTemp+="<Time>"+contents[3]+"</Time>";
sTemp+="<Change>"+contents[4]+"</Change>";
sTemp+="<Open>"+contents[5]+"</Open>";
sTemp+="<High>"+contents[6]+"</High>";
sTemp+="<Low>"+contents[7]+"</Low>";
sTemp+="<Volume>"+contents[8]+"</Volume>";
sTemp+="<MktCap>"+contents[9]+"</MktCap>";
sTemp+="<PrevClose>"+contents[10]+"</PrevClose>";
sTemp+="<PctChg>"+contents[11]+"</PctChg>";
sTemp+="<AnnRange>"+contents[13]+"</AnnRange>";
sTemp+="<Earns>"+contents[14]+"</Earns>";
sTemp+="<P-E>"+contents[15]+"</P-E>";
sTemp+="<Name>"+contents[16]+"</Name>";
sTemp+="</Stock>";
result+=sTemp;
sTemp="";
}
//Close the stream from the server
strm.Close();
result +="</StockQuotes>";
}
Finally,
we catch any exceptions, and return our result stream of valid XML (or
"exception", as the case may be):
catch(Exception)
{
//If exception occurred, provide user message
result="exception";
}
//Return StockQuote(s) or Exception
return result ;
}
}
Now if you simply load this page in your
browser, the .NET Platform will compile and cache it into IL (Intermediate
Language) and you can see the default "Webservice Discovery Channel"
page, as I like to call it. At this point, you should be able to pass
the input parameters on the querystring, use a SOAP method call, or even
use xmlHTTP to send the parameters to the service and get back the well-formed
XML response document containing your quotes. Just be sure to delimit
your quote symbols with spaces, as that's what Yahoo's server expects.
Your StockQuote WebService class will take care of the rest. If you append
"?SDL" to your URL to the service, you'll get a complete Service
Description Language document that completely describes your webservice,
its method(s), parameters and types.
My first example consumer page, which
is included in the download Zip file, uses a separate XSLT stylesheet
to transform the output to a nice HTML table. You can try out the online
StockQuotes
Webservice HERE.
I hope this gives you some ideas - its
like Remote Data Services on steroids, without the security BS. Back to
the Future!
Download the code that accompanies
this article.
Peter Bromberg is an independent consultant specializing in distributed .NET solutionsa Senior Programmer
/ Analyst at in Orlando and a co-developer of the EggheadCafe.com
developer website. He can be reached at pbromberg@yahoo.com
|