Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Make 'ToDo' System for Multi-Program Complex System: Part 1

0.00/5 (No votes)
18 Apr 2004 2  
Make 'ToDo' system for multi-program complex system, using ASP.NET & C#

Introduction

When I started learning programming with C#, I searched detailed articles about making complex systems step by step. I can't say that I found lot of them. I think this type of article can be used by beginner and advanced programmers (last skip some simple steps ;)). In this case, I planned a detailed description of developing my next project. The target of this project is to make a Log system with these features:

  • Manage messages from 'end users' of different programs, used in complex network data storage, analysis and transmit systems, to developers
  • Report errors from 'end users' and testers to developers
  • Manage 'ToDo' events

I will post all steps of developing progress in the next part of this article (but may be, I'll combine some steps in part one).

And now, we begin.

Part I

System Structure

The systems uses Client-Server architecture, where server-side is based on ASP.NET, and client side is a Class Library containing client-side forms and functions.

Starting (Step 1)

Server-Side

Server-Side is implemented using XmlWebService (for now only one, but maybe in future ...).

To start, we need only 2 methods on the server:

  • GetLog() - returns posted messages in XML format
  • PostMessage(string message) - posts a new message on server

GetLog Function

public XmlNode GetLog()
{
    string dpath = this.GetType().Assembly.CodeBase;
    dpath = dpath.Substring(dpath.IndexOf(":///")+4);
    dpath = dpath.Substring(0, dpath.LastIndexOf('/'));
    dpath = dpath.Substring(0, dpath.LastIndexOf('/')+1);

    XmlDocument xdoc = new XmlDocument();
    try
    {
        xdoc.Load(dpath+"todo_data.xml");
    }
    catch (Exception)
    {
        XmlNode root = xdoc.CreateElement("log");
        xdoc.AppendChild(root);
    }

    return xdoc.SelectSingleNode("/log");
}

in this code:

Determine Path to Storage Data File
dpath = dpath.Substring(dpath.IndexOf(":///")+4);
dpath = dpath.Substring(0, dpath.LastIndexOf('/'));
dpath = dpath.Substring(0, dpath.LastIndexOf('/')+1);

In case the Service is invoked in Windows System directory, we must determine its real storage directory (this is bin subdirectory in Web application directory). Path is returned in URI format with protocol name. On this step, we assume that protocol returned by stored path is always file:///. Crop it from path using String.Substring and String.IndexOf methods.

In one of the next steps, we must implement detection and cropping of other protocols.

In the result, path string become of the form [Drive:/Path to WEBApp root/bin/AssemblyName]. From that string, we crop AssemblyName and /bin (see source). In the result, we have path in the form [Drive:/Path to WEBApp root/].

Maybe this is not the best way to do this, but it is working :). If you know a better method, post it in comments.

Loading Stored Data, or Creating New Empty Data Storage

XmlDocument xdoc = new XmlDocument();
try
{
    xdoc.Load(dpath+"todo_data.xml");
}
catch (Exception)
{
    XmlNode root = xdoc.CreateElement("log");
    xdoc.AppendChild(root);
}

Why using try...catch block? XmlDocument.Load method throws exception if file is not found or if it finds errors in XML file while parsing. In this step, we don't worry about corrupt stored file (simply return empty result).

Returning Storage Data to Client

return xdoc.SelectSingleNode("/log");

XML file that stores data, has this structure:

<?xml version="1.0" ?>
<log> <!-- Root node -->
    <message posted="<!-- when posted -->"><!-- message text --></message>
    ................
    ................
    <message posted="<!-- when posted -->"><!-- message text --></message>
</log>

In result, to return messages to client, all we need is to find <log> node and return it as result.

PostMessage Function

public void PostMessage(string message)
{
    string dpath = this.GetType().Assembly.CodeBase;
    dpath = dpath.Substring(dpath.IndexOf(":///")+4);
    dpath = dpath.Substring(0, dpath.LastIndexOf('/'));
    dpath = dpath.Substring(0, dpath.LastIndexOf('/')+1);

    XmlDocument xdoc = new XmlDocument();
    try
    {
        xdoc.Load(dpath+"todo_data.xml");
    }
    catch (Exception)
    {
        xdoc.AppendChild(xdoc.CreateElement("log"));
    }
    XmlNode root = xdoc.SelectSingleNode("/log");
    XmlNode msg = xdoc.CreateElement("message");
    XmlAttribute msg_attr = xdoc.CreateAttribute("posted");
    msg_attr.InnerText = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
    msg.Attributes.Append(msg_attr);
    msg.InnerText = message;
    root.AppendChild(msg);
    xdoc.Save(dpath+"todo_data.xml");
}

in this code:

Determining storage path, loading to create data storage and finding root node for message making as in the previous function.

Creating New 'Message' Element and Saving Data
XmlAttribute msg_attr = xdoc.CreateAttribute("posted");
msg_attr.InnerText = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
msg.Attributes.Append(msg_attr);
msg.InnerText = message;
root.AppendChild(msg);
xdoc.Save(dpath+"todo_data.xml");

I think, this part of code doesn't need comments. (If needed, see articles about working with XML data in .NET and C#.)

Install and Use Code

This is all for this step. In the result, we have a simple WebService that allows us to store and retrieve messages.

To test this code, download the demo project and build it.

Copy code library for Web application located in web_bin directory to bin directory of your Web application. Create log.asmx file in root folder of your Web application. log.asmx file must contain only this row:

<%@ WebService language="C#" class="devel.Log" %>

In the next part, I will discuss how to make a simple client for this service, in C#.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here