Kniha návštěv v ASP.NET – bez použití databáze

13. září 2002

Kniha návštěv je dnes k dostupná prakticky na všech webových stránkách. Dnes si ukážeme, jak takovou knihu návštěv naprogramovat s pomocí technologie ASP.NET. Záměrně jsem ji vytvořil bez použití databáze, protože na některých webových serverech nemusí být databázový stroj vůbec nainstalován. Veškerý zápis dat tedy půjde na disk do předem vytvořených souborů.

Formulář pro odesílání dat je velmi jednoduchý, obsahuje pouze několik ovládacích prvků pro sběr dat, k nim přiřazené schvalovací prvky pro položky, které jsou povinné a jeden popisek (label) pro jejich zpětné zobrazení. Jeho zdrojový kód vypadá takto:

<!DOCTYPE HTML PUBLIC „-//W3C//DTD HTML 4.0 Transitional//EN“ >
<html>
<head>
<title>Kniha návštěv</title>
</head>
<body>
<form id=“Form1″ method=“post“ runat=“server“>
<blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“> <blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“> <blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“> <blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“> <blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“>
<div align=“justify“><font size=“5″>Kniha návštěv</font>
</div>
</blockquote></blockquote></blockquote></blockquote></blockquote>
<center><font size=“5″></font>
</center>
<div align=“left“>Jméno: <asp:textbox id=“txtName“ runat=“server“ Width=“393px“></asp:textbox>
&nbsp;
<asp:requiredfieldvalidator id=“RequiredFieldValidator1″ runat=“server“ Display=“Dynamic“ ControlToValidate=“txtName“ ErrorMessage=“Nutno zadat.“></asp:requiredfieldvalidator>
</div>
<div align=“left“>Email:&nbsp;&nbsp;
<asp:textbox id=“txtEmail“ runat=“server“ Width=“390px“></asp:textbox>
&nbsp;
<asp:regularexpressionvalidator id=“RegularExpressionValidator2″ runat=“server“ Display=“Dynamic“ ControlToValidate=“txtEmail“ ErrorMessage=“Zadáno v nesprávném formátu.“ ValidationExpression=“\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*“></asp:regularexpressionvalidator>
</div>
<div align=“left“>Web:&nbsp;&nbsp;
<asp:textbox id=“txtWeb“ runat=“server“ Width=“393px“></asp:textbox>
&nbsp;
<asp:regularexpressionvalidator id=“RegularExpressionValidator1″ runat=“server“ ControlToValidate=“txtWeb“ ErrorMessage=“Zadáno v nesprávném formátu.“ ValidationExpression=“http://([\w-]+\.)+[\w-]+(/[\w- ./?%&amp;=]*)?“></asp:regularexpressionvalidator>
</div>
<div align=“left“>Text:&nbsp;&nbsp;&nbsp;
<asp:textbox id=“txtText“ runat=“server“ Width=“395px“ Height=“135px“ TextMode=“MultiLine“></asp:textbox>
&nbsp;
<asp:requiredfieldvalidator id=“RequiredFieldValidator2″ runat=“server“ Display=“Dynamic“ ControlToValidate=“txtText“ ErrorMessage=“Nutno zadat.“></asp:requiredfieldvalidator>
</div>
<blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“> <blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“> <blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“> <blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“> <blockquote dir=“ltr“ style=“MARGIN-RIGHT: 0px“>
<div align=“left“>
<asp:button id=“btnSubmit“ runat=“server“ Text=“Odeslat“></asp:button>
</div>
</blockquote></blockquote></blockquote></blockquote></blockquote>
<div align=“left“>
<hr width=“100%“ size=“1″ />
</div>
<div align=“left“>
<asp:label id=“lblMessages“ runat=“server“></asp:label>
</div>
<div align=“left“>
</div>
</form>
</body>
</html>

Na pozadí formuláře, na straně serveru, pracuje tento kód:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
namespace guestbook
{
     public class Form : System.Web.UI.Page
     {
         protected System.Web.UI.WebControls.TextBox txtName;
         protected System.Web.UI.WebControls.TextBox txtEmail;
         protected System.Web.UI.WebControls.TextBox txtWeb;
         protected System.Web.UI.WebControls.TextBox txtText;
         protected System.Web.UI.WebControls.Label lblMessages;
         protected System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator1;
         protected System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator2;
         protected System.Web.UI.WebControls.RegularExpressionValidator RegularExpressionValidator1;
         protected System.Web.UI.WebControls.RegularExpressionValidator RegularExpressionValidator2;
         protected System.Web.UI.WebControls.Button btnSubmit;
         private void Page_Load(object sender, System.EventArgs e)
         {
             if (!Page.IsPostBack)
             {
                 StreamReader reader = new StreamReader(Server.MapPath(„guestbook.dat“));
                 reader.BaseStream.Position = 0;
                 lblMessages.Text = reader.ReadToEnd();
                 reader.Close();
             }
         }

V této části kódu je důležitý příkaz using System.IO;. Zajistí využití jmenného prostoru IO, ve kterém se nacházejí třídy pro práci se soubory. Dále je zde událost Page_Load, která provede kontrolu, zda jde o první načtení stránky, či již o její opětovné poslání a podle toho provede výpis ze souboru guestbook.dat. Otevře se nový „proud dat“ (Stream), u něhož se nastaví pozice kurzoru v proudu na počátek a celý se načte do popisku lblMessages.

Nejdůležitější obslužná funkce je přiřazena tlačítku Odeslat. Řídí veškerou programovou logiku pro kontrolu dat a jejich následný zápis do souboru.

public void btnSubmit_Click(object sender, System.EventArgs e)
{
     string strMessage;

     strMessage = „<b>“ + Server.HtmlEncode(txtName.Text) + „</b><br>“;
     if(txtEmail.Text != „“)
         strMessage += „<a href=\“mailto:“ + Server.HtmlEncode(txtEmail.Text) + „\“>“ + Server.HtmlEncode(txtEmail.Text) + „</a><br>“;
     if(txtWeb.Text != „“)
         strMessage += „<a href=\““ + Server.HtmlEncode(txtWeb.Text) + „\“>“ + Server.HtmlEncode(txtWeb.Text) + „</a><br>“;
     strMessage += „<br>“ + Server.HtmlEncode(txtText.Text) + „<hr>“;

Po stisknutí tlačítka na formuláři se začnou shromažďovat data do proměnné strMessage typu string. Proti uživatelům, kteří by chtěli zneužít stránku knihy návštěv pomocí různých HTML značek a skriptů, je zde programové ošetření každého přijímaného textu pomocí funkce Server.HtmlEncode. Kód se pak sice zpětně do stránky načte, ale nebude proveden, pouze vypsán. Pokud nebyly vyplněny prvky s webovou nebo emailovou adresou, nejsou zaneseny do proměnné strMessage.

    StreamReader reader = new StreamReader(Server.MapPath(„lastwrite.dat“));
     reader.BaseStream.Position = 0;
     string test = reader.ReadToEnd();
     reader.Close();
     if(test.Length > 1)
         test = test.Remove(test.Length – 2, 2);

Tento kód slouží k ošetření problému opětovného načtení stránky po jejím odeslání. Tak se v knize návštěv mohou za pár minut objevit stovky stejných příspěvků. Proto máme vytvořený ještě jeden soubor (lastwrite.dat), který obsahuje poslední vložený příspěvek.

    if(test != strMessage)
     {
         StreamWriter writer = new StreamWriter(Server.MapPath(„guestbook.dat“), true);
         writer.WriteLine(strMessage);
         writer.Close();

         StreamWriter writer1 = new StreamWriter(Server.MapPath(„lastwrite.dat“));
         writer1.WriteLine(strMessage);
         writer1.Close();
     }

Nyní se provede porovnání s právě vkládaným příspěvkem a pokud jsou rozdílné, zapíše se příspěvek do obou souborů. Datové proudy je důležité uzavírat příkazem Close() aby nedošlo k uzamčení souboru a tím k znepřístupnění celé aplikace.

    txtEmail.Text = txtName.Text = txtText.Text = txtWeb.Text = „“;

     StreamReader reader1 = new StreamReader(Server.MapPath(„guestbook.dat“));
     reader1.BaseStream.Position = 0;
     lblMessages.Text = reader1.ReadToEnd();
     reader1.Close();
}

Nakonec se vymaže obsah všech prvků a načte se obsah návštěvní knihy do popisku lblMessages.

Problém s opakovaným načtením stránky můžete řešit i vyhledáním zprávy, kterou se uživatel pokouší vložit, v souboru guestbook.dat. Při nalezení stejného příspěvku nedojde k vložení. Nebyl by tedy potřeba soubor lastwrite.dat, ale naproti tomu by se zvyšovalo použití souboru guestbook.dat, čímž by se zpomaloval běh aplikace protože přístup k  souboru může mít vždy pouze jeden uživatel (jedna session). Navíc se vyhledávání uskutěčňuje v paměti, je tedy nutné celý soubor do ní nahrát paměti, což určitě není (zvlášť pokud je soubor větší) vhodné pro zdroje serveru. K problému také dojde tehdy, kdy by příspěvek obsahoval krátké sdělení typu: ok, díky atp. Kód pro vyhledávání vypadá takto:

public void btnSubmit_Click(object sender, System.EventArgs e)
{
    string strMessage;

     strMessage = „<b>“ + Server.HtmlEncode(txtName.Text) + „</b><br>“;
     if(txtEmail.Text != „“)
         strMessage += „<a href=\“mailto:“ + Server.HtmlEncode(txtEmail.Text) + „\“>“ + Server.HtmlEncode(txtEmail.Text) + „</a><br>“;
     if(txtWeb.Text != „“)
         strMessage += „<a href=\““ + Server.HtmlEncode(txtWeb.Text) + „\“>“ + Server.HtmlEncode(txtWeb.Text) + „</a><br>“;
     strMessage += „<br>“ + Server.HtmlEncode(txtText.Text) + „<hr>“;

     StreamReader reader = new StreamReader(Server.MapPath(„guestbook.dat“));
     reader.BaseStream.Position = 0;
     string test = reader.ReadToEnd();
     reader.Close();

     if(test.IndexOf(strMessage) > 0)
     {
         StreamWriter writer = new StreamWriter(Server.MapPath(„guestbook.dat“), true);
         writer.WriteLine(strMessage);
         writer.Close();
     }
     txtEmail.Text = txtName.Text = txtText.Text = txtWeb.Text = „“;

     lblMessages.Text = test;
}

Celý soubor guestbook.dat je tedy načten do paměti do proměnné test. Pomocí podmínky test.IndexOf(strMessage) > 0 se vyhodnotí, zda se daný příspěvek již v knize návštěv vyskytuje a podle toho se vloží do souboru guestbook.dat.

Pro úplnou funkčnost aplikace je nutno nastavit uživateli ASPNET přístupová práva k souborům guestbook.dat a lastwrite.dat. Vše co dělá ASP.NET, dělá pod uživatelským účtem ASPNET (v rámci zvýšení bezpečnosti). Přiřazení práv je možno provést v Průzkumníku. Po označení obou souborů je třeba vybrat jejich vlastnosti a na záložce zabezpečení přidat uživatele ASPNET. Při nastavování oprávnění stačí zaškrtnout pouze Číst a Zapisovat.

Kniha návštěv je v důsledku omezených možností při práci se soubory poměrně jednoduchá. Její rozšíření a doplňování o nadstandardní funkce by bylo velmi náročné vzhledem ke konečnému efektu. Práce se soubory je navíc pro server velmi neefektivní. Nicméně pro menší weby nebo weby bez podpory databáze je dostačující. Příště si tedy ukážeme jak udělat stejnou knihu návštěv s pomocí databáze a ADO.NET.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *