WEBINAR:
On-Demand
Application Security Testing: An Integral Part of DevOps
Designing the Sample Application
The primary purpose of this application was to replace the whiteboard stuck to our kitchen refrigerator. While the whiteboard works well in terms of ease of use, it's limited to showing a single month at a time and subject to data loss if someone happens to smudge the writing when retrieving an afternoon snack. It's also time consuming to redraw a new calendar at the beginning of each month. Besides, I can't check that calendar from work!
If cross-platform is one of your end goals in designing an application, you'll want to watch for any code tied to a particular operating system. For example, platform-specific filenames and file paths will cause problems if you aren't careful. Little things such as case sensitivity will bite you when you try to run the application on a different platform. Instead, use built-in features such as the
Server.MapPath method to discover your application directory at runtime rather than hard coding paths to a specific location.
This simple example consists of a single Web form containing a calendar control and a data grid. One XML file holds an entire year's worth of appointments. The application reads the XML file into a single DataSet when it first loads. It then displays the current month with appointment details displayed for the proper day (see
Figure 1).
 | |
Figure 1. The Family Calendar Application: The application reads appointment data from an XML file into a DataSet and displays the current month by default with the appointments displayed in the appropriate day cells of the calendar. |
Implementation
Writing the code was not that difficult. Even if you're a novice at C# you'll find lots of examples with a few simple Google queries. The Microsoft Visual Studio documentation and MSDN Web site are full of good information as well. I get a lot of good tips from reading Web logs. For example, the
http://weblogs.asp.net site gathers feeds from various writers both inside and outside of Microsoft and aggregates them into a single feed.
One thing I really like about Visual Studio is the ability to create an ASP.NET page by just dragging and dropping controls onto the design surface. Once you have the controls on the page (a calendar control and a DataGrid in this case), you set the visual properties, add a few event handler stubs, and you're ready to code.
For this application, the
events.xml file holds the information for each event in a single record with the date, time, and description. Here's what the file looks like with three events:
<?xml version="1.0" encoding="utf-8" ?>
<events>
<event>
<Date>2004/8/5</Date>
<Time>5:00</Time>
<Description>Soccer Practice</Description>
</event>
<event>
<Date>2004/8/10</Date>
<Time>9:00</Time>
<Description>Dr. Appt</Description>
</event>
<event>
<Date>2004/8/10</Date>
<Time>11:00</Time>
<Description>Lunch w/ Carol</Description>
</event>
</events
To access a DataSet from any function within a page, you must instantiate it as a class-level variable. Place the code immediately after the calendar and DataGrid definitions inserted by the VS designer:
protected DataSet dsEvents = new
DataSet("events");
Reading in the file requires one line of code:
dsEvents.ReadXml (Server.MapPath ("events.xml"));
After loading the file, the DataSet contains a single table named
event with three columns that hold the date, time, and description for each event. The application then loops through each item for the current month in the
event database using the
foreach keyword and renders each day individually using the
DayRender function.
private void Calendar1_DayRender(object sender,
System.Web.UI.WebControls.DayRenderEventArgs e)
{
DataGrid1.DataSource = dsEvents;
foreach (DataRow myDataRow in
dsEvents.Tables["event"].Rows)
{
string s = myDataRow["Date"].ToString();
if (s != "")
{
DateTime event_date = DateTime.Parse(s);
if ( (e.Day.Date == event_date) &&
(!e.Day.IsOtherMonth))
{
Label aLabel = new Label();
aLabel.Text = " <br>" +
myDataRow["Time"].ToString() + " " +
myDataRow["Description"].ToString();
aLabel.Font.Size = FontUnit.XSmall;
e.Cell.Controls.Add(aLabel);
}
}
}
}