Develop a composite custom server control in ASP.NET to add instant, up-to-date, reusable, remote data for your Web projects
Technologies Used:
ASP.NET
C#
XML
XSLT
Custom Server Control programming model
JavaScript
Level of Difficulty
Advanced
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.
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
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.
Enjoy…and happy programming!
</jason>