Insider Information: tap the market and add a NASDAQ stock ticker to your Web site


by Jason Salas, KUAM.COM
April 11, 2003

 

Past editions:

Implementing custom validation in ASP.NET with the CustomValidator class

Building a newsletter management system in ASP.NET with C#: Part 2

Program a time-coding application to calculate read-times

Building a newsletter management system in ASP.NET with C#: Part 1

A simple document management system in ASP with XML and XSLT

Password-protect your Web work

Error Handling in VBScript

Creating a banner ad rotation system

The Web-safe color palette for developers

Time-saving Windows shortcuts

Analyzing your site's traffic logfiles

Develop a composite custom server control in ASP.NET to add instant, up-to-date, reusable, remote data for your Web projects

Technologies Used:

Level of Difficulty


Everyone involved in Web development knows that content is king. Not matter how large, diverse, or functional a site or application is, it’s critical to have a rich palette of diverse data to offer visitors to ensure they can find something useful and come back in the future (hopefully soon). And no matter how good the data you provide on your own, it’s always great to have outside help. One of the best examples of featuring such external data that’s highly demanded is by providing your users with stock quote information.

Web-based Stock tickers are timely, topical, and in demand from everyone from corporate executives, to students, to small-time investors. They’re also a utility that’s all over the place now, when 50 years ago the only people who had their own stock tickers were financial gurus or the rich.

Download the source code files for this project

This week, we’re going to tackle our most ambitious Web development project yet: developing a composite custom server control in ASP.NET that delivers customizable stock data to your pages. And we’ll logically use the most tech-rich stock index, the NASDAQ. In this case, insider information isn’t against the law…in fact, it’s encouraged!

Here's a sample of the NASDAQ stock ticker control in action:

Insider Information
The good folks at NASDAQ have been kind enough, by using technologies developed by HyperFeed, to develop a means of programmatically accessing their massive data store for live stock quotes and profiles of the securities listed on their index (delayed by 20-minutes, and limited to a maximum of 10 securities at a time). By specifying what stocks you’d like to lookup on NASDAQ, the output is provided as XML data. So, this gives developers a plethora of avenues with which to access, format, manipulate, and manage the data within their own applications.

With the .NET Framework, we’ll use concepts and programming models that promote encapsulation and reusability, all while writing a minimal amount of code.

Our goals for developing this control are to:
1. create a service that lots of people could use to get stock quote data
2. make the stock ticker easy to use
3. have it be customizable for the page developer
4. have the control auto-reload so that data is kept as fresh as possible

To achieve all of the above using ASP.NET, the obvious answer is to develop a custom control. We’ll author a class that will inherit from the Control base class, and contain all the functionality and output to add to parent pages. We’ll then compile this class as an assembly (a .DLL file), saving it to our Web application’s \BIN subdirectory. (We could also make this a globally-accessible custom control by using the Global Assembly Cache (GAC), but this is beyond the scope of this tutorial and as such we won’t go there.)

Being a compiled object, the custom control is easily transported to different Web servers for use in Internet, intranet and extranet applications. It’s also very easy to use in code, just requiring two short lines of code to add to a page. And because it’s a compiled object, our custom control’s data members are accessible either programmatically or declaratively, making it more appealing to both programmers and page layout artists alike. We’ll also introduce some client-side JavaScript code to have the custom control reload on its own automatically. This will ensure that the data is kept current, without forcing the user to manually refresh the entire page that can be bothersome to a site’s users.

So in theory, we’ve nailed all four of our objectives.

But enough yapping – let’s write some code!


Behind the Scenes
The NASDAQ service gets the data for companies through stock symbols passed through a query string. A sample query string, finding the values for some companies I personally invest in, namely Microsoft, Sun Microsystems, Intel, Disney, AOL-Time Warner, Cisco Systems, Adobe Systems, Comcast, eBay, and Starbucks follows:
http://quotes.nasdaq.com/quote.dll?mode=stock&page=xml&symbol=MSFT&symbol=SUNW&symbol=INTC&symbol=DIS&symbol=AOLA&symbol=CSCO&symbol=ADBE&symbol=CMCSA&symbol=EBAY&symbol=SBUX


User Interface
There’s nothing groundbreaking in the front-end aesthetics of our composite custom control. Essentially, we’re having the XML data from NASDAQ populate an HTML <MARQUEE> element, to achieve the impression of a scrolling stock ticker. Since the source data is coming down the wire in XML, we’re going to need to transform it using XSLT. I wrote a simple formatting scheme, formatting gains as green text and losses as red text for each security. You can see my XSLT syntax in the code download, and you can certainly come up with your own implementation, as well.



Composite Custom Server Control Development
Let’s break down the construction of our custom control systematically. First, we know that our data will be accessed remotely by making a remote procedure call (RPC) to NASDAQ’s distant-end data store, resulting in XML data. So, we’ll be using the .NET Framework’s System.Xml and System.Xml.Xsl namespaces to access/parse and transform/format the data into a format that’s acceptable for us, respectively. So in authoring our control class, we import those namespaces at the top of the file in lines 7 and 8 to gain access to their members.

Because .NET’s XML technologies are being used, we’re binding the data to an XML server control that will be contained as a child control within the main control. Thus, we’re developing a composite custom server control, and to structure the output we’ll be overriding the CreateChildControls() method from the base Control class rather than overriding the base class’s Render() method.

Looking at the code in our class file (KUAMStockTicker.cs), you’ll notice that in line 12 we inherit from the base Control class, and implement the INamingContainer interface. The former (or the WebControl superclass) is required when authoring custom controls; the latter is a marker interface (one with no methods) that assures that all child controls added to the page’s control tree upon rendering are unique, thus avoiding potentially catastrophic name clashes (for example, two TextBox controls with an ID attribute of “txtName”). Although this isn’t going to be much of an issue with this particular custom control, it’s good practice whenever you develop composite custom controls to implement INamingContainer.


 

In the class definition, four private variables are declared in lines 15-18 to hold the data that ultimately is used in the control’s public read/write properties, which are defined in lines 21-42. Specifically, you can see the StockSymbols, XSLSource, BackgroundColor properties being of type String, and TimeDiffFromEST being of type int. Take a moment to note how each property handles the data. StockSymbols accepts a string of stock symbols separated by a semi-colon (“;”). XSLSource sets a relative path to the physical location of the XSLT document on the Web server’s disk, and BackgroundColor uses the value “beige” as a default background color for the <MARQUEE> if no other value is given. As with HTML attribute values, the values for BackgroundColor may be set using their names (“Burlywood”) or their hexadecimal values (“#DEB887”).

We then define a string object, and set it to have the first arguments for the NASDAQ query string. The individual page developer can enter up to 10 stock symbols to query, again, either programmatically in code or declaratively on a page. We then define the GetStockSymbols() private helper method in lines 49-57 that takes the value of the StockSymbols property as an argument of symbols to query. A C# foreach statement is used to get the string of stock symbols and separate each into a character array by using the Split() method, and concatenating them to our query string construct. We end up with a full query string that will be used as an argument to access NASDAQ’s data store.

So now, we’re at the meat of our control class definition. We override the base Control class’s CreateChildControls() method starting in line 60, so that our custom control elements and the child controls contained within can be added to the page’s control tree. Let’s go through each step of the process:

STEP 1: the helper method defined earlier is called to get the query string.
STEP 2: the code instantiates new instances of an XmlDocument and an XslTransform object. We use the Load() method from each of class to dynamically load the source data from NASDAQ, as well as to find the XSLT document that defines the transformation and formatting of the XML data (the latter is accessed through the XSLSource property defined earlier).
STEP 3: a client-side function is written in JavaScript to automatically refresh the page every 20 minutes, and the client-side script block is registered to the page framework in lines 82-85. Since this is being encapsulated to a custom control, the control will be reloaded on the page. This keeps the real-time practicality of the control and greatly enhances its worth to a consuming client.
STEP 4: a Label server control is declared on line 88, with its Text property set to reflect whether active trading is going on, or not. Again, functionality is enhanced by giving the page developer the ability to set what time zone she’s in by accessing the difference in hours from U.S. Eastern Standard Time (negative values are accepted for time zones ahead of EST). This makes the control more localizable, further enhancing its functionality.
STEP 5: each of the controls is added to the page’s control tree by calling the Add() method of the page’s Controls collection. Both programmatic controls and literal HTML markup are added to be rendered as output.  Also note the setting of the id, onMouseOver and onMouseOut attributes within the <MARQUEE> tag.  The id attribute appends a randomly-generated number to give it a "unique" quality in the case when multiple instances of the control are used on a page.  onMouseOver and onMouseOut invoke the stop() and start() methods, respectively of the <MARQUEE> tag to pause the scrolling of the data.

Additionally, I made sure to invoke the EnsureChildControls() method in the Page_Load event. Because child controls rendered I custom control aren’t rendered until after the page’s Load event finishes, a developer wouldn’t have access to the object and its properties. This ensures that a developer can access your object in the Page_Load event properly, and like other tricks mentioned above, is good practice to get into the habit of doing.

If you’ve developed custom controls before, you might be wondering why the base class Render() method isn’t overridden. This is because when developing composite controls and overriding the CreateChildControls() method, all of the rendering if taken care of by the page framework.


Compiling Your New Control
Now that all the code is written, to complete the authoring of the composite custom server control we need to compile the class file to an assembly. Use the following commands with the C# compiler at a command prompt within the current directory to compile your class:

csc /t:library /out:NasdaqStockQuotes.dll /r:System.dll /r:System.Web.dll /r:System.Xml.dll KUAMStockTicker.cs

The only thing remaining is to copy the .DLL file generated by the compiled into your Web application’s \BIN folder, and voila! It’s ready to be used in your Web projects!


Using the Control in Your Pages
Now that the control has been properly authored and compiled as an assembly, you need only to reference it in your .ASPX pages via the Register declaration at the top of the page. Developers can set whatever value they like for the TagPrefix attribute, but must use “dgf.utilities.customcontrols” for the Namespace attribute (since this is the namespace assigned to the custom control), and properly using the class name of “KUAMStockTicker”.  For example:

<% @ Register TagPrefix="kuamcom3" Namespace="dgf.utilities.customcontrols" Assembly="NasdaqQuotes" %>

Again, the API for the KUAMStockTicker control only exposes four public properties - StockSymbols, XSLSource, BackgroundColor and TimeDiffFromEST - each of which gets and sets the values for the various properties so the control is more customizable.  The custom control can then be declared on an ASP.NET WebForm as any other server control would be (note the relationship of the properties declared within the control as those developed in the control class):

Declaratively:
<kuamcom3:KUAMStockTicker id="quotes" StockSymbols="MSFT;SUNW;INTC;DIS;AOLA;CSCO;ADBE;CMCSA;EBAY;SBUX" XSLSource="nasdaq-stockinfo.xslt" BackgroundColor="Oldlace" TimeDiffFromEST="-14" runat="server"/>

Programmatically:
KUAMStockTicker quotes = new KUAMStockTicker();
quotes.StockSymbols = “MSFT;SUNW;INTC;DIS;AOLA;CSCO;ADBE;CMCSA;EBAY;SBUX";
quotes.XSLSource = “nasdaq-stockinfo.xslt”;
quotes.BackgroundColor = “Oldlace”;
quotes.TimeDiffFromEST = -14;


The best thing about this control is its ease of use. We could have arguably saved time by wrapping the functionality in a user control (an .ASCX file), but then if we wanted to use it repeatedly within the same page, we’d have to write multiple <% @ Register … %> declarations corresponding to each instance of a control on a page. With our custom control, we need only to use a unique ID attribute, set the properties, and we’re set! You could use such multiple controls on a single page for keeping track of stocks by industry, such as technology, healthcare, and automotive firms, setting different BackgroundColor and StockSymbols properties for each. We can also take it “on the road” and just drop the .DLL in \BIN directories on other servers and start working instantly.

However, if you don’t want to repeat authoring all of this code, you can find the .DLL file in the code download as well as a sample client and get install it to run on your own Web site – instantly. The best thing is that so can others. They just copy and go. Simple!

I tried to develop this composite custom server control to illustrate how simplistic .NET development and code management is. The resultant control is pretty cool to use, but obviously, there is a lot more functionality that could be added and/or modified within the control. Feel free to play with your own ideas, and write me with changes or enhancements that you’ve built-in on your own. I’d love to hear about them and see how you’ve used this in your own development projects.

Download the source code files for this project


Enjoy…and happy programming!
</jason>