ASP.NET AJAX framework provides us with two types of patterns to build richer, more interactive, standards-based Web 2.0 applications: the server-centric programming model and client-centric one, with each holding its own advantages and disadvantages. According to Dino Esposito, "For now, however, the best way out is to implement AJAX through the UpdatePanel control." For now, we are suggested to follow the server-centric programming model to develop ASP.NET AJAX based applications. After more than two years of researching into the ASP.NET AJAX framework, I greatly approve of his viewpoint. The server-centric programming model enables you to “…modify existing pages at your convenience. Also, it's unobtrusive and doesn't require you to learn many new things before starting.”
In contrast, although the ASP.NET AJAX Client-Centric programming model can leverage full power of client-side JavaScript/XHTML and provide cross-browser richer and more interactive user experience, developers have to spend plenty of time to grasp multifold related techniques of both the server side and the client side. Especially Visual Studio 2005, but even the newest Visual Studio 2008 has not provided better support for the client-side xml-script declarative programming mode, which in some degree adds the difficulty in writing the xml-script code.
In this series (3 articles), I will try to show you how to follow the ASP.NET AJAX server-centric programming model to develop a mini blog system under ASP.NET 2.0 environments. In this first installment of this series, we are going to focus upon the general design related issues, while in the second part we are to construct the backend system around the manager management, and in the last part to discuss the common user related things as well as conclude the crucial techniques and skills utilized in the blog system.
A weblog, sometimes written as web log or Weblog, often has the quality of being a kind of "log of our times" from a particular point-of-view. It is the fourth important means of intercourse by internet in succession to e-mail, BBS, and ICQ (IM). Generally, weblogs are devoted to one or several subjects or themes, usually of topical interest, and, in general, can be thought of as developing commentaries, individual or collective on their particular themes. A weblog may consist of the recorded ideas of an individual (a sort of diary) or be a complex collaboration open to anyone. Most of the latter are moderated discussions.
In this mini blog sample application presented to you, the theme is mainly limited to computer associated topics (of course you can alter it on you own cases). And for brevity, we have not provided the reverse chronological order based post classification, while merely accomplished a category based one.
OK, before delving into the inner workings of the mini blog system, let us first take a quick look at the several main running time snapshots of it to gain a more intuitionistic and clearer understanding.
The testing environment and tools used in this article are as follows:
· Windows XP Professional (with IIS 5.1 installed)
· Visual Studio 2008 (with the built-in support for ASP.NET AJAX Extensions)
· SQL Server 2005
· ASP.NET AJAX Control Toolkit
Therefore, to gain a better understanding with the mini blog website project provided in this article, you are required to be familiar with ASP.NET 2.0/3.5 C# programming, SQL Server programming, and ASP.NET AJAX framework. In addition, you are highly recommended to download the source files accompanying this article (see the download URL at the end). Last but not least, for the convenience of those still under the Visual Studio 2005 environment, I tried to utilize the ASP.NET 2.0 compatible controls though I have developed this sample application under Visual Studio 2008. So, with a little modification, you can easily get it through under Visual Studio 2005.
For brevity, we herein are going to exhibit to you only a few of the key running-time snapshots related to the blog system. Figure 1 describes the homepage of the blog system when the administrator has not logged in (note: for an integral view of the long page, I pieced together the key parts of it - you can clearly catch sight of them from the red marks).
Figure 1: The homepage of the blog system
As is apparently shown, the whole interface is divided into four parts: the top is a simple system log picture, the bottom is a typical and common page footer, and the middle corresponds to the main part—the left panel is classified into several typical sub control panels to better manipulate the system and the right will indicate the detailed contents that corresponds to the user gestures at the left panel.
It is worth noting that in real scenarios there are usually advertising blocks left for the third-party companies, the recommended position for which should be located in a third column to be added for you later. However, still for brevity, we omitted them all.
In fact, Figure 1 happens to correspond to the common user mode in this application, in which mode the user bears the ability to read the blog articles, view the current blog associated comments left by other surfers, navigate to the current host linked favorite hyperlinks, as well as leave a word to the current blog host provided he or she is logged in the system.
Also, it is noted that the two important techniques leveraged herein are updating the page in the AJAX mode (partially and asynchronously), and url redirection for easy understanding and recollection. For related details, please read on.
Now, let us continue to see what the interface looks like after the administrator has logged into the system. Figure 2 gives one of the related running-time snapshots.
Figure 2: One of the running-time snapshots of the backend management of the blog system
Note that as an administrator (and, for simplicity, the blog host herein), you can manipulate the blog category, blog articles, comments left by passengers, your own interested hyperlinks, and words (opinions) to the blog host left by permitted readers, all of which are constructed under ASP.NET 2.0/3.5 environments with the help of ASP.NET AJAX components. Note that Figure 2 just relates to the blog articles management snapshot.
Note that herein we are to omit introducing the operation flow since you will easily catch on it when we introduce the system module relationships.
Based on the fact that we are developing a demo blog system and mainly focusing our interests upon how to make use of the ASP.NET AJAX server-side techniques, I choose to use the simplest two-tier architecture to build the sample rather than fall back on the three-tier or even the newest ASP.NET MVC ones (all of which are recommended architectures in practical case).
As is well known, in the two-tier architecture you can directly access the backend database in each page of the presentation tier without implementing the individual database interface. Advantages and disadvantages are apparent: the developing and debugging processes are greatly simplified while the maintenance will become fussy and even more difficult.
At any rate, let us examine the two-tier architecture applied to this mini blog system, as is depicted in Figure 3.
Figure 3: The two-tier architecture utilized in this mini blog system
Apparently, in the two-tier module we are able to directly manipulate the backend system via .aspx web pages (the presentation tier). In detail, through the web pages, we can directly achieve all the operations such as adding, modifying, or deleting the data persisted in the SQL Server database.
System Functionality Modules
The sample website, named AajxMiniBlog in this article, provides different functionalities according to the corresponding role of the users. On the whole, there are two kinds of roles in this system: the administrator (and, for simplicity, the blog host) and the common user (any common surfers). The former owns the right of category management, blog management, comments management, and hyperlinks management while the common users are assigned the rights to browse blogs and related comments, leave a word, as well as make comments on their interested blogs.
As of now, you can clearly understand that the whole system is easily divided into two parts from the view point of the user roles, as in illustrated in Figure 4 and Figure 5.
Figure 4: The blog administrator modules
Figure 5: The common users related modules
With the general architecture and modules in mind, let us roll up our sleeves to start to work. But first of all, let us dissect at the database design and its related tables together with the relationships between them one by one.
In this case, we will design a SQL Server database named ST_BLOG_DATA.mdf, which contains seven tables with each taking their own responsibilities listed below.
—ST_admin for holding users info. For simplicity we have not included the user registration module. The default system administrator name and password are admin and 1 respectively. And also, we have not added any blog host user info—you can add them on your own situation.
—ST_class to hold the blog categories to facilitate the blog article management.
—ST_link to hold the hyperlinks to other blogs that the blog host user shows interest in.
—ST_message to hold all the words left to the current blog host by the valid users.
—ST_news to hold all the blog articles written by the current blog host.
—ST_replay to hold comments made to the current blog article by the valid readers.
—codetable to hold authentication info used to distinguish the human being operations from the robot ones.
Next, to achieve a better understanding with these tables above, I listed each of their schema definitions in table form below.
Designing the tables
The following tables give the corresponding structure definitions and field notes of the tables mentioned above, respectively.
Table 1: Structure for table ST_admin
Field name
Type
Notes
ST_admin_user
nvarchar(50)
Can be null.
The administrator user name.
ST_admin_psw
The password corresponding to ST_admin_user field above.
Table 2: Structure for table ST_class
ST_c_id
bigint
IDENTITY (1,1) NOT NULL, Primary Key.
The auto incremental category id.
ST_c_name
NOT NULL.
The blog category name.
Table 3: Structure for table ST_link
ST_l_id
The auto incremental id for the hyperlink that the blog host is interested in.
ST_l_name
nvarchar(100)
The shortened hyperlink name.
ST_l_url
The complete url for the above hyperlink.
Table 4: Structure for table ST_message
ST_id
The auto incremental id for the message that valid passenger leaves.
ST_nickname
The nickname of the passenger that leaves the word.
ST_title
The title of the word.
ST_homepage
The title of passenger’s homepage.
ST_content
ntext
The details of the words left.
ST_mdate
datetime
The datetime when the word was left.
ST_hf
Mark when the left word is replied or not in text mode.
Table 5: Structure for table ST_news
ST_n_id
int
The auto incremental id for the blog article.
ST_n_author
The author name of the blog.
ST_n_title
nvarchar(200)
The title of the blog.
ST_n_key
The abstract of the blog.
ST_n_content
The details of the blog.
ST_n_date
The datetime for posting the blog.
ST_n_hit
The times of the blog read by surfers.
ST_n_re
The times of replies for this blog.
Foreign key.
ST_n_iscmd
bit
Mark when the left word is replied or not in text string.
Table 6: Structure for table ST_replay
ST_r_id
The auto incremental id for the comment.
ST_r_nick
The nick name of the comment.
ST_r_title
The title of the comment.
ST_r_content
nvarchar(250)
The details of the comment.
ST_r_date
The datetime for making the comment.
Table 7: Structure for table codetable
Id
The field that identifies the id of the code for the CAPTCHA verification usage.
Code
nchar(20)
Cannot be null. The text string to achieve the CAPTCHA verification.
With the table schemas established, we should further familiarize ourselves with the relationships between the tables introduced above.
Set up the Table Relationships
Figure 6 illustrates the table reference dependencies defined inside the database ST_BLOG_DATA.mdf (I created the database diagram inside Visual Studio Team System 2008; or you can create it using SQL Server 2005/2008).
Figure 6: The reference relationships between the tables
Again, since this system is a simplified version there are no complex reference dependencies between the above tables, but there are still few relations between the three tables as is easily caught sight of from the figure.
About the Common Modules
Only two points need to be noticed here: the database connection mode and the general layout of the system.
As for the database connection, I select to directly put the sample database under the sub-folder App_data of the website for you to more easily debug the system. However, in real cases, the databases commonly reside in the SQL Server side which is located at independent machines. So, the database connection string will be different under these cases. Herein, we only consider the above simplest situation as indicated in the config file web.config below.
Code Listing 1
<connectionStrings> <add name="ConnectionString" connectionString= "Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\ST_Blog_Data.MDF; Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" /> </connectionStrings>
As for the general layout of the system, we select to leverage the master page introduced in ASP.NET 2.0 since it is the recommended means to construct real case projects. In our case, there are two types of master pages: Admin.master (for backend management content pages) and OneColumn.master (for login.aspx and Message.aspx). Moreover, for greater flexibility we have also put into use two common ASP.NET Web forms—index.aspx and Show.aspx.
Next, let us set out for the long journey to write the mini blog system one by one. The first part comes to you is the login system.
In this case, we have not utilized the normal and strict ASP.NET authenticating system, but adopted a simple login means, which is accomplished through page Login.aspx. Figure 7 gives the related design-time snapshot.
Figure 7: The design-time snapshot of page Login.aspx
First, we should notice that now Visual Studio 2008 provides the ability to add "AJAX Master Page" template directly, which results in an ASP.NET AJAX ScriptManager control being added into the master page. Therefore, we now (in the content page) are unable to see the control. Next, we can see this login content page contains only a few simple ASP.NET controls as well as two ASP.NET AJAX Control Toolkit extender controls - TextboxWatermarkExtender (which is used to achieve the watermark effect with the TextBox control adminname) and PasswordStrength (which is used to intuitively remind the users of the password strength of what they enter into the password textbox control). And also, we used the simplest ASP.NET validator, RequiredFieldValidator, to ensure the user does enter something.
Next, let us look more closely at the crucial HTML mark code, as shown in Listing 2.
Listing 2: The key HTML mark code in page Login.aspx
<tr> <td width="50%" > <div align="center">User Name:</div> </td> <td style="text-align: left"> <asp:TextBox id="adminname" runat="server" CssClass="cssUnwatermark" Width="228px"></asp:TextBox> <asp:RequiredFieldValidator id="rfN" runat="server" ControlToValidate="adminname" Text="The name field cannot be empty!" InitialValue="Please enter username here..." Display="Dynamic" > </asp:RequiredFieldValidator> <asp:RequiredFieldValidator ID="rfv2" ControlToValidate="adminname" Text="The name field cannot be empty!" Display="Dynamic" runat="server" /> <cc1:TextBoxWatermarkExtender ID="TextBoxWatermarkExtender1" runat="server" TargetControlID="adminname" WatermarkCssClass="cssWatermark" WatermarkText="Please enter username here..."> </cc1:TextBoxWatermarkExtender> </td> </tr> <tr> <td ><div align="center">Password:</div> </td> <td style="text-align: left"> <asp:TextBox id="adminpsw" runat="server" TextMode="Password" style="text-align: left" Width="227px"></asp:TextBox> <asp:RequiredFieldValidator id="RequiredFieldValidator2" runat="server" ErrorMessage="The password field cannot be empty!" ControlToValidate="adminpsw"></asp:RequiredFieldValidator> <cc1:PasswordStrength ID="PasswordStrength1" runat="server" TargetControlID="adminpsw" StrengthIndicatorType="Text" HelpHandlePosition="AboveRight" DisplayPosition="BelowRight" MinimumNumericCharacters="1" MinimumSymbolCharacters="1" PrefixText="Strength:" PreferredPasswordLength="6" TextCssClass="texttype" TextStrengthDescriptions="Weak;Not enouth;Medium;Strong;" HelpHandleCssClass="help" HelpStatusLabelID="Label1"> </cc1:PasswordStrength> <br /> <asp:Label ID="Label1" runat="server" Width="369px"></asp:Label> </td> </tr> <tr> <td ><div align="center">Please confirm your password:</div> </td> <td style="text-align: left"> <asp:TextBox id="PasswordStr" runat="server" TextMode="Password" style="text-align: left" Width="227px"></asp:TextBox> <asp:CompareValidator ID="CompareValidator1" runat="server" ControlToCompare="adminpsw" ControlToValidate="PasswordStr" ErrorMessage="The password is different from the previous one!"> </asp:CompareValidator> </td> </tr> <tr > <td height="25" colspan="2"> <div align="center"> <asp:Button id="Button1" runat="server" Text="Login" onclick="Button1_Click" CssClass="ButtonCss" Width="104px"> </asp:Button> [<a href="Index.aspx">Back to Home</a>] </div> </td> </tr>
It is worth noting that for brevity we select to omit explaining the two simple ASP.NET AJAX Control Toolkit extenders. Therefore, for more details concerning their usage you can refer to the downloaded source code at the end as well as the tutorial site for ASP.NET AJAX Control Toolkit controls.
Author’s Notes: In constructing an ASP.NET AJAX Server-Centric based website, you are recommended to use ASP.NET server controls as much as possible rather than the client-side HTML controls in order to set up your system more rapidly. However, what is better to choose will in the end fall back upon your own familiarity with the tools at hand.
When the button "Login" is clicked, its related click event handler is triggered. Listing 3 gives the related code snippet.
Listing 3: The key code for file Login.aspx.cs
public partial class Login : System.Web.UI.Page { SqlConnection ST_myConn; protected void Page_Load(object sender, EventArgs e) { string ST_dns = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; ST_myConn = new SqlConnection(ST_dns); } protected void Button1_Click(object sender, EventArgs e) { SqlCommand ST_myCmd = new SqlCommand( "select * from ST_admin where ST_admin_user='" + adminname.Text.Trim() + "' and ST_admin_psw='" + adminpsw.Text.Trim() + "'", ST_myConn); ST_myConn.Open(); SqlDataReader ST_read = ST_myCmd.ExecuteReader(); if(ST_read.Read()) { //store the value of field ST_admin_user into Session Session["UserName"]=ST_read[0].ToString(); //redirect the user to the page Admin_Admin.aspx Response.Redirect("Admin_Admin.aspx"); } else { Response.Write( "<script>alert('Sorry,the username and password are incorrect!')</script>"); } } }
In function Page_Load, we found the database connection string from file web.config and set up the connection using the ADO.NET object—SqlConnection. Next, when button "Login" is clicked, its click event handler Button1_Click is invoked. As you have seen, here we directly worked with the SELECT SQL clause which represents the typical two-tier architecture operation.
Note that at the very beginning of designing table ST_admin there is only a record in it—the value of field ST_admin_user being "admin" and the value of field ST_admin_psw being "1." So, according to your own situation, you can add by hand to the table any other records that describe the valid users (often blog hosts). In this case, when the current user is verified to be the valid user, he will be navigated to the backend administrator management related page, Admin_Admin.aspx.
Again, for simplicity, we grant the sale privileges to the administrator and the blog host, while in real scenarios this may not necessarily be the case.
So far the discussion has been about page login.aspx. Next we switch our topic to the homepage of the system, index.aspx.
Now that Figure 1 gives you the running-time snapshot of the homepage index.aspx, let us continue to look at its related design-time snapshot as is shown in Figure 8.
Figure 8: The design-time snapshot of page Index.aspx
As is easily seen from Figure 8, the left sub panels correspond to several ASP.NET 2.0 DataList controls with associated data attached to them at the running time. When you click the "Login" button you will be navigated to page Login.aspx. The "Blogs" panel shows to the surfers all the existing blog categories while the "Comments" panel indicates all the possible comments made to related blog articles. The "Favorite Links" panel shows the current blog host's interested favorite blog hyperlinks. The "Leave a word" under panel "About Me" will lead you to the page Message.aspx for you to leave a possible word to the current blog host which will be detailed in the third part of the article.
Now, let us focus on the AJAX related topics in this page. In fact, as you may have guessed, when the user clicks the left hyperlinks the right part will present to you the related contents, which is a typical case to put into use the ASP.NET AJAX server control UpdatePanel so as to achieve the partial updating effect in the asynchronous way.
The following Listing 4 gives the related pieces of HTML mark code.
Listing 4: The interesting UpdatePanel related HTML mark code in the homepage
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:datagrid id="NewsList" runat="server" PageSize="20" AutoGenerateColumns="False" HorizontalAlign="Center" AllowPaging="True" OnPageIndexChanged="Get_Page" Width="98%" CellPadding="0" BorderColor="Maroon" BorderStyle="Solid" BorderWidth="2px"> <Columns> <asp:TemplateColumn> <HeaderTemplate> <a href="Index.aspx" style="font-size:xx-large">Home</a> <span style="font-size:xx-large">-></span> <a href="#" style="font-size:xx-large"> <%= Request.QueryString["name"]%></a> </HeaderTemplate> <ItemTemplate> <table width="98%" border="0"> <tr> <td colspan='2' > <div > <a href='<%# DataBinder.Eval(Container.DataItem, "ST_n_id") %>.aspx'> <%# DataBinder.Eval(Container.DataItem, "ST_n_key")%></a></div> </td> </tr> <tr> <td colspan="2"><b>Abstract</b>: <%# DataBinder.Eval(Container.DataItem, "ST_n_id")%> </td> </tr> <tr > <td align="right" colspan="2">[<a href='<%# DataBinder.Eval(Container.DataItem, "ST_n_id") %>.aspx'>Click and Read</a>] Read:[<%# DataBinder.Eval(Container.DataItem, "ST_n_hit")%>] Comment:[<%# DataBinder.Eval(Container.DataItem, "ST_n_re")%>] Time:[<%# DataBinder.Eval(Container.DataItem, "ST_n_date")%>]</td> </tr> </table> </ItemTemplate> </asp:TemplateColumn> </Columns> <PagerStyle NextPageText="next>>" PrevPageText="<<prev" PageButtonCount="20" Mode="NumericPages"></PagerStyle> </asp:datagrid> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="ClassList" EventName="ItemCommand" /> <asp:AsyncPostBackTrigger ControlID="ClassList" EventName="SelectedIndexChanged" /> </Triggers> </asp:UpdatePanel>
First, you should notice that the UpdateMode property of control UpdatePanel "UpdatePanel1" is set to "Conditional." As you have found at the end, this UpdatePanel control owns two AsyncPostBackTrigger triggers which correspond to the two events (ItemCommand and SelectedIndexChanged) of DataList control "ClassList."
Next, since the trivial inner contents of the DataList control is purely ASP.NET related issues and not complex to grasp, it is not worthy to be discussed in detail any more.
Downloads
[Download Sample]
We have finished up introducing the general design of the blog system, with two additional pages, login.aspx and index.aspx, also introduced. In the next part of the article we will delve into the backend administrator management related issues.
User Comments