深蓝海域KMPRO

Building a Stock-Quotes Web Service

2002-09-12 14:43

Building a Stock-Quotes Web Service

 

Saurabh Nandu

March 20 2001

Level: Beginner

Download Source Code

Demo this code

Introduction

I guess you might be having some information on what Web Services. If not you can read .net101's article about Web Service Part 1 -Basics. In the current article we will be concentrating on building and consuming a Web Service which delivers "Stock Quotes" on the .NET Platform. We will be using Yahoo's free service which provides "Stock Quotes" in CSV (Comma Separated Values) format and wrap it up in our web service.

Note: The quotes run around 15 minutes late and should only be used for educational purposes.

 Building the Web Service

We will step through the code to understand the Web Service programming model in .NET. To write our Web Service you can use any text editor like notepad to type your code and save it as StockQuote.asmx.
Note: All Web Service files are saved with the extension *.asmx.

<%@ WebService Language="C#" class="DailyStock" %>

The first line of our code defines a Web Service and the language used to be "C#". The class attribute is used to denote the class which the Web Service should call and expose. If you are using many classes in your Web Service use this attribute to denote the class that should be called first by the Web Service.

using System ;

using System.Web.Services ;

using System.Net ;

using System.IO ;

using System.Text ;

Import the necessary Namespaces. The Namespaces System.Web.Services should be always be imported, remaining Namespaces should be imported on the basis of the requirements of your class.

public class DailyStock : WebService

{

......

....

}

Here we define our public class DailyStock, which extends the System.Web.Services.WebService class. All the classes that you want to expose as Web Services should extend the System.Web.Services.WebServices class. Also the access modifier for the Web Service class should always be public.

[WebMethod]

public string GetQuote(string symbol)

{

........

........

}

Above we define a public Web Method GetQuote. As in classes Web Methods also have to be declared with the public modifier. The [WebMethod] attribute renders the underlying method to be exposed to the Web Service. So all the methods that you want the clients to access should be marked with the [WebMethod] attribute.

The GetQuote method takes one input parameter, a string containing the symbol for which the consumer wants the quote. The method responds back with a string containing the stock quote or error messages if any.

string ret;

try

{

  // The Path to the Yahoo Quotes Service

  string fullpath =

@"
http://quote.yahoo.com/d/quotes.csv?s="+symbol+"&f=sl1d1t1c1ohgvj1pp2owern&e=.csv";

  // Create a HttpWebRequest object on the Yahoo url

  HttpWebRequest webreq = (HttpWebRequest)WebRequestFactory.Create(fullpath);

  // Get a HttpWebResponse object from the Yahoo url

  HttpWebResponse webresp = (HttpWebResponse)webreq.GetResponse();

  // Create a StreamReader object and pass the Yahoo Server stream as a parameter

  StreamReader strm = new StreamReader(webresp.GetResponseStream(), Encoding.ASCII);

  // Read a single line from the stream (from the server)

  // We read only a single line, since the Yahoo server returns all the

  // information needed by us in just one line.

  ret= strm.ReadLine();

  // Close the stream to the server and free the resources.

  strm.Close();

}

catch(Exception)

{

  // If exception occurred inform the user

  ret="Exception Occurred" ;

}

//Return the Quote or Exception

return ret ;
 
This is the contents of the GetQuote method. We use a try-catch block to intercept any errors that can occur while getting the stock quotes from Yahoo. Inside the try-catch block we declare a string variable which holds the full path to the yahoo service. The symbol string variable that the consume provides gets added to this connection string (shown in bold letters).

Once the path is constructed we make a HttpWebRequest object and a HttpWebResponse out of the connection string. Next we open up a stream to the Yahoo server using the StreamReader. The StreamReader reads one line from the server since all information that we need is provided by Yahoo in a single line. Finally the stream is closed and the output from Yahoo is returned to the Consumer.

Deploying the Web Service

Deploying the Web Service is similar to the deployment of a ASP.NET application. If you have your own web server then create a virtual directory called stockquote (you can use any name you want.) and then copy the StockQuote.asmx into this directory. This completes the Web Service deployment. To call the Web Service fire up your browser and type the path to the Web Service i.e. http://localhost/stockquote/StockQuote.asmx. The page you see is automatically generated for you by the Web Services runtime. Type the symbol (like AOL or MS etc) in the textbox provided and click the invoke button. A new browser will pop-up showing you the output of the Web Service.

 Consuming the Web Service

There are basically two ways to consume Web Services. You can either call the Web Service directly through your browser and use it which we have done above. The second method is to use some application to consume it. We will see how to build a Web Application and a Console Application which will consume our Web Service. You can alternatively use Win Form Applications to consume the Web Service.

 Get the Service Description

In order to communicate with the Web Service the client should know what methods are supported by the Web Service and how to communicate with them. Web Services on .NET automatically produce a XML formatted document in SDL (Service Description Language) to enable the clients gain the information they need to communicate with Web Services. Appending ?SDL after the Web Service URL causes to Web Service to generate the SDL document that the clients can use. To view the SDL of our Web Service type http://localhost/stockquote/StockQuote.asmx?SDL in your browser.

 Build the Proxy Library

Applications on the .NET Platform can use Proxy libraries to call methods on a Web Service which makes consuming Web Service very easy. First step in generating a proxy library is to generate a proxy class out of the SDL of the Web Service. The .NET SDK provides a tool called WebServiceUtil.exe which helps us to generate a proxy class. To generate a proxy class of our Web Service start-up your command prompt (ms-dos prompt) and navigate to the directory in which you will be developing you client application. Then enter the following command:

WebServiceUtil /c:proxy

 /pa:http://localhost/stockquote/StockQuote.asmx?SDL 

 /n:Quotes

The above command generates a C# source code file called DailyStock.cs (Web Service class name is also DailyStock, remember!) in the directory from which you ran this command. Let's see what the arguments mean.

/c:proxy

It tells the WebServiceUtil to generate a proxy class

/pa:http://localhost/stockquote/StockQuote.asmx?SDL

Supplies the path to the SDL of the Web Service. If you have saved the SDL of the Web Service to your Hard Disk you can even provide the local path to the SDL file.

/n:Quotes

Tells the tool to place the proxy class in the "Quotes" Namespace. We do this so it is easy to manage and consume our proxy library.

Once we have the proxy class ready, we use the C# compiler to generate a proxy library out of the proxy class we just created in the above step.

csc /target:library /r:System.dll;System.Web.Services.dll;System.Net.dll;

System.IO.dll;System.Xml.Serialization.dll DailyStock.cs 
 
While generating the proxy library we use the /target:library switch to indicate that we want a library file as a output. Also we reference some assemblies that we have used in our Web Service. The compiler will generate a library dll by the name DailyStock.dll in the directory the command was run.

 Creating a Web Application Consumer

We will create a Web Application as our first consumer of the StockQuote Web Service. StockConsumer.aspx

<%@ Page language="C#"  %>

<%@ Import Namespace="System.Xml" %>

<%@ Import Namespace="Quotes" %>

Import the necessary Namespaces. Remember to import the Quotes Namespace too, which is the Namespace of your proxy class

<html>

<head>

<script runat=server>
 
// Wire up the onClick event for a button
 
protected void button1_Click(object sender, EventArgs e)
 
{
   
//Create a object of the class DailyStock (the proxy class)
   
DailyStock ds = new DailyStock();

// Call the GetQuote method of the proxy class DailyStock and
   
// pass the symbol string from the textbox
   
string res = ds.GetQuote(symbol.Text);
 
// The returned string has values which are separated
   
// by commas.
   
// Hence we split the returned string into parts
   
char[] splitter = {','} ;
   
string[] temp = res.Split(splitter);

 // Check if the string array returned has more than one
   
// elements since if there are less than one elements
   
// then an exception must have been returned
   
if(temp.Length >1)
   
{
     
// The WebService returns a lot of information about the
     
// stock. We only show the relevant portions
     
// Set the label to current Index
     
curindex.Text = "Current Index :"+temp[1]; 
     
// Set the label to current Date Time
     
curdate.Text ="Last Update on"+temp[2]+" at "+temp[3]; 
   
}
   
else
   
{
     
error.Text = "Error :"+res ; //set the error label
   
}
 
}

</script>

Above in the script tag on the ASP.NET page we first instantiate a instance of the class DailyStock (Web Service). Since we have generated the proxy library calling methods of the Web Service is similar to calling methods on any other library. We call the GetQuote() method of the DailyStock class which returns a string containing the full information of the symbol in a comma separated list.

We will restrain our client to display only the current index and the date/time on which the index was recorded. In order to break up the string into different parts we use the Split method of the string class to split the string into parts on the occurrence of every comma. Once we have the spitted array of strings we just set the different labels of the Web Page with the relevant values. 

Rest of the code

<body>

<center>

<h2>.NET101 Stock Quote Consumer </h2>

<form runat=server >

<table border=1 celspacing=1>

<tr><th>Please enter the symbol below</th></tr>

<tr><td>
 
<asp:textbox id=symbol runat=server />&nbsp;
 
<asp:button id=button1 text="Get Quote"
        
onClick="button1_Click" runat=server />

</td></tr>

<tr><td><asp:label id=curindex runat=server /></td></tr>

<tr><td><asp:label id=curdate runat=server /></td></tr>

<tr><td><asp:label id=error runat=server /></td></tr>

</table>

</form>

</center>

</body>

</html>

Deploying the Web Application

Create a virtual directory named StockConsumer.

Copy the StockConsumer.aspx file to this virtual directory.

Now create a "bin" virtual directory in the wwwroot folder if you don't already have one.

Give permissions to the bin directory to execute code.

Now copy the proxy dll DailyStock.dll to this directory. The bin directory is the directory from which the ASP.NET runtime engine automatically picks up references to external libraries in our case the DailyStock.dll.

Now call the file
http://localhost/StockConsumer/StockConsumer.aspx. Enter the symbol for the stock and click on "Get Quote" button and see you Web Service being consumed. Note: your Web Service should be able access the yahoo server or it will return a exception.

相关推荐