The guest book on ASP.NET

The application ASP.NET, written from the beginning and up to the end, represents the guest book


To download source codes - 22 kb <http: // codeproject.com/aspnet/GuestbookLK/Guestbook.zip>


Vvvedenie


This project enables visitors to leave messages in the guest book on a site. The project will consist of two parts:

?         Creation of messages.

?         Viewing the guest book.


Database


The guest book will be saved in a XML-file guestbook.xml on the server. The coding of a XML-file is changed on ISO-8859-1 that it was possible to process special symbols. Structure of a XML-file:

<? xml version = " 1.0" encoding = "ISO-8859-1"?>

<guestbook>

    <guest private = "yes">

        <name> Laurent Kemp? t;/name>

        <homepage url = " http: // perso.wanadoo.fr/laurent.kempe / "> Tech Head </homepage>

        <location> Illzach, France </location>

        <comment> First to sign the guestbook;) </comment>

        <date> Thursday, May 30, 2002 - 10:29 AM </date>

    </guest>

</guestbook>



It will be offered to you to enter the following information:

?         A name

?         E-Mail

?         The name of a home page

?         URL a home page

?         The address

?         Comments

?         PRIVATE - I want, that only the owner of a site saw mine email


The application


To have an opportunity it is easy to change a method of display of the guest book, it is required to divide{share} a code and the data. For performance of this requirement I have chosen use of XSLT-transformation of a XML-file; thus to users the HTML-file comes back.

Creation of messages


The page which allows users to leave messages in the guest book, contains in the Web-form ' Sign.aspx '. This page demands from the user to fill in some fields (textboxes) infomaciej which will be displayed in the guest book. To check the entered information, we use RequiredFieldValidator. Besides we also use RegularExpressionValidator for check of Email address.


When the visitor has filled in all fields, he presses the button of continuation, and the page returns event, perekhvatyvaemoe method ButtonContinue_Click. This method loads database XML, receives the information entered by the user, and adds her  in the beginning of a XML-file. Then the new database is saved on a disk of the server and the user perenapravljaetsja on page of viewing.

private void ButtonContinue_Click (object sender, System. EventArgs e)

{

    // To load a database of the guest book

    XmlDocument xmldoc = new XmlDocument ();

    xmldoc. Load (Server. MapPath ("guestbook.xml"));


    // To receive the status private

    string strPrivate;

    if (CheckBoxPrivate. Checked)

        strPrivate = "yes";

    else

        strPrivate = "no";


    // To create a new element

    XmlElement elem = xmldoc. CreateElement ("guest");

    elem. SetAttribute ("private", strPrivate);


    // To add the new message in the first site

    xmldoc. DocumentElement. PrependChild (elem);


    addTextElement (xmldoc, elem, "name", TextBoxName. Text);

    addTextElement (xmldoc, elem, "email", TextBoxEMail. Text);

    addTextElement (xmldoc, elem, "homepage", TextBoxHomepageTitle. Text);


    XmlAttribute newAttr = xmldoc. CreateAttribute ("url");

    newAttr. Value = TextBoxHomepageURL.Text;


    elem. LastChild. Attributes. Append (newAttr);

     

    addTextElement (xmldoc, elem, "location", TextBoxLocation. Text);

    addTextElement (xmldoc, elem, "comment", TextBoxComments. Text);


    // To write down date

    string strDate = DateTime. Now. ToLongDateString () +

                     "-" +

                     DateTime. Now. ToLongTimeString ();


    addTextElement (xmldoc, elem, "date", strDate);


    xmldoc. Save (Server. MapPath ("guestbook.xml"));


    Response. Redirect ("view.aspx");

}



We used a method addTextElement for construction of the new message of the user in a database:

private void addTextElement (XmlDocument doc, XmlElement nodeParent,

                             string strTag, string strValue)

{

    XmlElement nodeElem = doc. CreateElement (strTag);

    XmlText nodeText = doc. CreateTextNode (strValue);

    nodeParent. AppendChild (nodeElem);

    nodeElem. AppendChild (nodeText);

}



Viewing


For viewing all recordings the guest book we have added one more Web-form ' View.aspx ' in the project. In method Page_Load we have loaded database XML and a XSLT-file. We have executed transformation and have deduced{removed} result in an element of management Literal Web Form.

private void Page_Load (object sender, System. EventArgs e)

{

    // To load a database of the guest book from a xml-file

    XmlDocument doc = new XmlDocument ();

    doc. Load (Server. MapPath ("guestbook.xml"));


    // To receive number{room} of the requested page

    string strPageAsked = Request. QueryString ["page"];


    // If the page is not determined, to use the first

    if (strPageAsked == null)

    {

        strPageAsked = "1";

}


    int nGuestPerPage = 5;

    int nGuests = doc. ChildNodes [1] .ChildNodes. Count;


    int nPageAsked = System. Convert. ToInt32 (strPageAsked);


    int lowerbound = 1 + (nPageAsked - 1) * nGuestPerPage;

    int upperbound = lowerbound + nGuestPerPage - 1;


    // To execute XSLT-transformation

    XslTransform xslt = new XslTransform ();

    xslt. Load (Server. MapPath ("guestbook.xslt"));


    // To construct the list of parameters XLST

    XsltArgumentList xsltArgs = new XsltArgumentList ();

    xsltArgs. AddParam ("lowerbound", " ", lowerbound. ToString ());

    xsltArgs. AddParam ("upperbound", " ", upperbound. ToString ());


    // To transform XML in HTML

    MemoryStream ms = new MemoryStream ();

    xslt. Transform (doc, xsltArgs, ms);

    ms. Seek (0, SeekOrigin. Begin);


    StreamReader sr = new StreamReader (ms);


    // To insert results into page View.aspx

    LiteralGuests. Text = sr. ReadToEnd ();


    // To insert the navigator of pages in the bottom of page

    int nPages = 0;

     

    if ((nGuests % nGuestPerPage)! = 0)

        nPages = 1 + (nGuests / nGuestPerPage);

    else

        nPages = (nGuests / nGuestPerPage);


    LiteralGuests. Text + = " Page (s) ";


    for (int n = 1; n <= nPages; n ++)

    {

        LiteralGuests. Text + = " <font face ='verdana ' size = '2'> "

        LiteralGuests. Text + = " <a href = '/Guestbook/View.aspx? page = ";

        LiteralGuests. Text + = n. ToString ();

        LiteralGuests. Text + = " '> ";

        LiteralGuests. Text + = n. ToString ();

        LiteralGuests. Text + = " </a> </font> ";

}


    sr. Close ();

}



All transformation from XML in HTML are carried out in a file guestbook.xslt. This transformation uses two parameters: lowerbound and upperbound, representing bottom and top value of indexes of the messages, corresponding to displayed page of the guest book.

The basic, that we have made are a cycle from lowerbound up to upperbound and transformation:

<xsl:for-each select = " // guest [position () <= $upperbound and position ()> = $lowerbound] ">

    <xsl:apply-templates select = "name"/>

</xsl:for-each>



Example of the transformation used for display of the visitor and it  email if not the flag private is determined:

<xsl:template match = "name">

    <xsl:choose>

        <xsl:when test = ".. / private ='yes' ">

            <font face = "verdana" size = "2">

                <b> <xsl:value-of select = '. '/> </b>

            </font>

        </xsl:when>

        <xsl:otherwise>

            <font face = "verdana" size = "2">

                <b> <a HREF = " mailto: {../email} "> <xsl:value-of select = '. '> </a> </b>

            </font>

        </xsl:otherwise>

    </xsl:choose>

</xsl:template>



You can see a file guestbook.xslt for the further information.

The conclusion


I wanted to show, that it is important to divide{share} the data from processes of their performance, and in it very much helps XML. If you want to change performance of the guest book, you need to change only a file guestbook.xslt.