Developing an ASP.NET AJAX Server Centric Based Mini Blog System - Part 2
 
Published: 04 Aug 2008
Abstract
In the previous part, Xianzhong Zhu discusses the general architecture of the blog system which he is developing. In this second part, you will master the management of the blog application. He provides comprehensive coverage of the creation of various administration back-end tools like category, article, link, and message management modules with the help of relevant screenshots and source code.
by Xianzhong Zhu
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 27941/ 28

Overview

In the first part of this long article we introduced the general architecture of the sample blog system and took a quick look at the login system and the homepage layout. Although you are just setting your feet on the long journey, you should become aware that during the construction of an ASP.NET AJAX Server-Centric based system the ASP.NET techniques themselves still play the leading role, while the ASP.NET AJAX server controls together with the numerous ASP.NET AJAX Control Toolkit extenders only play the minor role. And again, we should firmly bear in mind that the key features of AJAX lies in the two aspects--the ASYNCHRONOUS mode and PARTIAL update. At the same time, no matter how many ASP.NET AJAX Control Toolkit extenders you put into use in your system, they merely help to extend the client-side functionalities and enhance the user experience to some extent. That is to say, the setup of the business logics of the system still falls back upon the ASP.NET platform itself as well as the related backend supporting languages such as C# and VB.

Moreover, to achieve the aim of bringing to the website a completely brand-new user experience requires that the developer be very familiar with the extender components, which in turn possibly cost a great deal of time. So, as you have may guessed, we have also utilized just a few of the AJAX Control Toolkit extenders with merely the aim to gain some AJAX experience in combination with the ASP.NET 2.0 techniques.

In this second part we will roll up our sleeves to write the blog sample application from the point of view of the background manager management.

But first of all, let us take a back look at the backend manager management related modules and their relations, as is depicted in Figure 1.

Figure 1 - The backend administrator related modules

Now with the backend modules in mind, we can start to dwell upon the above modules one by one.

The Backend Administrator Management

Before discussing the backend administrator system, there is a little episode needed to be pointed outthe placeholder page Admin_Admin.aspx.

About the placeholder page - Admin_Admin.aspx

When the user succeeds in logging into the system, he or she will be navigated to page Admin_Admin.aspx. As you will later discover in the source code, page Admin_Admin.aspx plays the role of a placeholder for us to more easily add the ASP.NET 2.0 SiteMapPath control related navigator technique. Figure 2 shows the running time interface when the administrator first logs in.

Figure 2 - The running time snapshot when the administrator first logs in

As you see, the placeholder page does nothing but serve as a simple placeholder in order to gain a coherent user experience with the ASP.NET 2.0 navigator support.

Now, let us first examine the blog category management block.

Blog Category Management - Admin_Type.aspx

The blog category management interface is the simplest yet most typical one in the system, which embodies the typical ASP.NET 2.0 server controls programming in combination with the ASP.NET AJAX server control UpdatePanel.  First take a look at the beginning running time snapshot for the blog category management, as is shown in Figure 3.

Figure 3 - The running time snapshot for the blog category management

As you have guessed, besides the left panel component that derives from the master page and the navigating bar at the upper right, there are four functionalities provided in this page: browse the blog category in page navigating mode, edit the category, delete it, and add new one by clicking button "Add new category."

It us worth noting that the first three functionalities have been well supported by the ASP.NET 2.0 GridView control, but for some unknown reason it has not had the built-in support for adding new records.

Now let us first review the conventional support of the GridView control for browsing, editing, and deleting, all of which are accomplished through the simple ASP.NET 2.0 declarative programming, as is indicated in Listing 1 (for integrity we list all the HTML mark elements code in this page).

Listing 1 - The typical declarative GridView control programming plus ASP.NET AJAX server-side control UpdatePanel

<%@ Page Language="C#" MasterPageFile="~/Admin.master" AutoEventWireup="true" 
CodeFile="Admin_Type.aspx.cs" Inherits="Admin_Type" Title="Untitled Page"%>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
 
    <script runat="server">
    void btnCancel_Click(object sender, EventArgs e)
    {
        GridView1.ShowFooter = false;
    }
    void btnAdd_Click(object sender, EventArgs e)
    {
        TextBox ArticleCategory = 
            GridView1.FooterRow.FindControl("ArticleCategoryTextBox") as TextBox;
        SqlDataSource1.InsertParameters["ST_c_name"].DefaultValue = 
            ArticleCategory.Text;
        SqlDataSource1.Insert();
    }
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" 
  Runat="Server">
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
    <table style="width: 75%;">
        <tr>
            <td colspan="3">
                <asp:SiteMapPath ID="SiteMapPath1" runat="server">
                </asp:SiteMapPath>
            </td>
        </tr>
        <tr>
            <td colspan="3">
                  <table width="98%" border="2" cellpadding="0" cellspacing="0" 
                      class="table" bordercolor="#006600">
                        <tr>
                              <td >
                              
                               <asp:Button ID="outAdd" runat="Server" 
                                   Text="Add new category" 
                            onclick="outAdd_Click"  />
                               
                        <asp:GridView ID="GridView1" runat="server" 
                            AllowPaging="True" 
                            AutoGenerateColumns="False" DataKeyNames="ST_c_id" 
                            DataSourceID="SqlDataSource1" Width="487px"
                            ShowFooter="False">
                            <Columns>
                                <asp:TemplateField HeaderText="ST_c_id" 
                                    InsertVisible="false"
                                    Visible="false">
                                    <EditItemTemplate>
                                        <asp:Label ID="Label1" runat="server" \
                                            Text='<%# Eval("ST_c_id")%>' />
                                    </EditItemTemplate>
                                    <ItemTemplate>
                                        <asp:Label ID="Label1" runat="server" 
                                            Text='<%# Bind("ST_c_id") %>' />
                                    </ItemTemplate>
                                </asp:TemplateField>
                                <asp:TemplateField HeaderText="Category" >
                                    <EditItemTemplate>
                                        <asp:TextBox ID="TextBox1" runat="server" 
                                            Text='<%# Bind("ST_c_name") %>' />
                                    </EditItemTemplate>
                                    <ItemTemplate>
                                        <asp:Label ID="Label2" runat="server" 
                                            Text='<%# Bind("ST_c_name")%>' />
                                    </ItemTemplate>
                                    <FooterTemplate
                                         Runat="server" />
                                     <asp:Button ID="btnAdd" Runat="server" 
                                         Text="Add" OnClick="btnAdd_Click" /> 
                                     <asp:Button ID="btnCancel" Runat="server" 
                                         Text="Cancel" OnClick="btnCancel_Click" /> 
 
                                  </FooterTemplate>
    
                                </asp:TemplateField>
                                    
                                    
                                <asp:TemplateField HeaderText="Operation" >
                                    <EditItemTemplate>
                                        <asp:LinkButton ID="LinkButton1" 
                                            runat="server" CausesValidation="True" 
                                            CommandName="Update" Text="Update"
                                            BackColor="White"></asp:LinkButton>
                                        <asp:LinkButton ID="LinkButton2" 
                                            runat="server" CausesValidation="False"
                                            CommandName="Cancel" Text="Cancel"
                                            BackColor="White"></asp:LinkButton>
                                    </EditItemTemplate>
                                    <ControlStyle ForeColor="#C00000" />
                                    <ItemTemplate>
                                        <asp:ImageButton ID="LinkButton1" 
                                            runat="server"
                                            CausesValidation="False" CommandName="Edit"
                                            ImageUrl="~/images/edit.gif"  
                                            ToolTip="Edit the current category">
                                        </asp:ImageButton>
                                        <asp:ImageButton ID="LinkButton3" 
                                            runat="server" CausesValidation="False" 
                                            CommandName="Delete"
OnClientClick="return confirm('Are you sure to delete this category?');"  
                                            ImageUrl="~/images/delete.gif" 
                                            ToolTip="Delete the current category">
                                        </asp:ImageButton>
                                    </ItemTemplate>
                                </asp:TemplateField>                                    
                                    
                         </Columns>
                        
                        </asp:GridView>
                        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 
DeleteCommand="DELETE FROM [ST_class] WHERE [ST_c_id] = @ST_c_id" 
InsertCommand="INSERT INTO [ST_class] ([ST_c_name]) VALUES (@ST_c_name)"
SelectCommand="SELECT * FROM [ST_class] " 
UpdateCommand="UPDATE [ST_class] SET [ST_c_name] = @ST_c_name WHERE [ST_c_id] = @ST_c_id">
                            
                            <DeleteParameters>
                                <asp:Parameter Name="ST_c_id" Type="Int32" />
                            </DeleteParameters>
                            <UpdateParameters>
                                <asp:Parameter Name="ST_c_name" Type="String" />
                            </UpdateParameters>
                            <InsertParameters>
                                <asp:Parameter Name="ST_c_id" Type="Int32" />
                                <asp:Parameter Name="ST_c_name" Type="String" />
                            </InsertParameters>                     
                         </asp:SqlDataSource>
                        </td>
                        </tr>
                  </table>
            </td>
        </tr>
    </table>
    </ContentTemplate>
    </asp:UpdatePanel>
 
</asp:Content>

To gain the paging support we set the GridView1's AllowPaging property to true. To make the GridView1 support the editing operation related "update" and "cancel" functions we must specify the UpdateCommand as well as the UpdateParameters related contents as shown above. The same logic applies to deleting function.

Next, let us check out how the adding (inserting) function is accomplished. Enhancing the GridView control with insert operation has several solutions you can retrieve from the Internet. So in this case, I will only present to you one of these.

As you may have guessed, the tip lies in the Footer part of the GridView control. To begin, we set the ShowFooter property to false. Next, when the user wants to insert (or add) a new record he or she can click the button "Add new category," which will trigger the handler outAdd_Click in file Admin_Type.aspx.cs.

Listing 2

protected void outAdd_Click(object sender, EventArgs e)
{
    GridView1.ShowFooter = true;
}

Then the footer part of GridView1 is displayed.

Figure 4 - Extend the GridView control to support inserting operation

When you enter a non-empty string and click "Add," the insert will succeed; or else, you can click "Cancel" to cancel the current operation (hide the footer of the GridView control).

Herein you have to code the two buttons related click event handlers in the inline mode.

Listing 3 - The inline mode click event handlers

    <script runat="server">
    void btnCancel_Click(object sender, EventArgs e)
    {
        GridView1.ShowFooter = false;
    }
    void btnAdd_Click(object sender, EventArgs e)
    {
        TextBox ArticleCategory = 
GridView1.FooterRow.FindControl("ArticleCategoryTextBox") as TextBox;
        if (ArticleCategory.Text.Trim() != "")
        {
            SqlDataSource1.InsertParameters["ST_c_name"].DefaultValue = 
ArticleCategory.Text;
            SqlDataSource1.Insert();
        }
    }
</script>

Otherwise, you will see a build error throw out

Figure 5 - In the ASP.NET content page mode too deep level of programming requires the inline mode, otherwise you will get the related build error

Last but not the least, the three modified operations are done in the AJAX modeall of the related areas are enclosed using an UpdatePanel control.

In the above case, we have only introduced one of the cases of the usage of the UpdatePanel control in terms of the master page. In fact, not all ASP.NET 2.0 controls are compatible with the UpdatePanel control. That ASP.NET 2.0 controls are compatible with the UpdatePanel control implies that ASP.NET 2.0 controls can be put inside the UpdatePanel control. That some ASP.NET 2.0 controls are incompatible with the UpdatePanel control implies that some ASP.NET 2.0 controls cannot be put inside the UpdatePanel control. However, the ASP.NET 2.0 controls that are incompatible with the UpdatePanel control can still be put on an ASP.NET AJAX page while the rest must be placed outside control UpdatePanel.

To sum up, the following ASP.NET 2.0 controls cannot be used inside control UpdatePanel.

·         TreeView and Menu

·         WebParts

·         FileUpload (it cannot be used when sending out files in the asynchronous way)

·         GridView and DetailsView controls with the EnableSortingAndPagingCallbacks properties setting True. Note that, by default, the EnableSortingAndPagingCallbacks properties of the both are set to false.

·         Substitution

·         Login, PasswordRecovery, ChangePassword, CreateUserWizard controls that have not been changed into editable temples

·         Validators, including BaseCompareValidator, BaseValidator, CompareValidator, CustomValidator, RangeValidator, RegularExpressionValidator, RequiredFieldValidator, and ValidationSummary controls

All in all, there are many, many things about the UpdatePanel control which can not be deeply researched in this article.

OK, let us next continue to see how the concrete blog articles are managed.

Blog Article Management - Admin_Article.aspx

Look at the design-time layout of the web form Admin_Article.aspx, as illustrated in Figure 6.

Figure 6 - The design-time snapshot of page Admin_Article.aspx

 

Page Admin_Article.aspx is also an ASP.NET AJAX typed content page. The middle part of the page is an UpdatePanel-enclosed GridView to show general blog info while the right is an UpdatePanel-enclosed DetailsView to display the related detailed blog info when one of the blogs at the middle part is clicked. Note the blog article deletion operation is directly done inside the GridView control, while the editing and appending operations are finished through the right part DetailsView. Moreover, if some error occurs during the course of the above operations, the Label ErrorMessageLabel is used to show the associated info, while when the editing is successfully done the related updating time will also be shown at the lower right part of control DetailsView. To make all of these a partial updating operation, we have also put them inside the UpdatePanel control.

As of other AJAX related topics, there are also three points deserved to be noticed. First, because the control DetailsView is surrounded alone by an UpdatePanel UpdatePanel2, when the updating operation takes effect in it, to achieve the result of synchronously update the data inside the GridView at the middle part, we set the DetailsView as the PostBackTrigger trigger of UpdatePanel UpdatePanel2, while GridView1 is set as the AsyncPostBackTrigger trigger. At this rate, when you click "Select" link inside the GridView, the contents in the right-side DetailsView control will be updated asynchronously, while when you edit and update the data in the DetailsView control, the data inside the middle GridView will be updated in the traditional post back way. Listing 4 below shows the related code.

Listing 4 - The PostBackTrigger and AsyncPostBackTrigger triggers of control UpdatePanel2

<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" 
            CellPadding="4" DataKeyNames="ST_n_id" DataSourceID="SqlDataSource3" 
            Font-Size="Smaller" Height="50px"
            Width="472px" ForeColor="#333333" GridLines="None" 
            OnDataBound="DetailsView1_DataBound"
            OnItemInserted="DetailsView1_ItemInserted" 
            OnItemUpdated="DetailsView1_ItemUpdated">
…… (omitted)
 
    </ContentTemplate>
    <Triggers>
        <asp:PostBackTrigger ControlID="DetailsView1" />
        <asp:AsyncPostBackTrigger ControlID="GridView1" 
            EventName="SelectedIndexChanged" />
        <asp:AsyncPostBackTrigger ControlID="GridView1" EventName="RowDeleted" />
        <asp:AsyncPostBackTrigger ControlID="GridView1" EventName="Sorted" />
        <asp:AsyncPostBackTrigger ControlID="GridView1" 
            EventName="PageIndexChanged" />
    </Triggers>
</asp:UpdatePanel>

Second, to gain the better user experience when users edit the blog authoring related date time, we introduced the AJAX Control toolkit extender CalendarExtender.

Listing 5 - The AJAX Control toolkit extender CalendarExtender related code

<asp:TemplateField HeaderText="Date" SortExpression="ST_n_date">
    <ItemTemplate>
        <asp:Label ID="Label3" runat="server" Text='<%# Bind("ST_n_date") %>' />
    </ItemTemplate>
    <EditItemTemplate>
        <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("ST_n_date") %>' />
        <asp:Image runat="Server" ID="Image1"
            ImageUrl="~/Images/Calendar_icon.gif"
            ToolTip="Click the icon to show the calendar." />
        <ajaxToolkit:CalendarExtender ID="CalendarExtender1" runat="server"
            TargetControlID="TextBox3"
            Format="MM/dd/yyyy"
            FirstDayOfWeek="Monday"
            PopupButtonID="Image1">
        </ajaxToolkit:CalendarExtender> 
    </EditItemTemplate>
    <InsertItemTemplate>
        <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("ST_n_date") %>' />
        <asp:Image runat="Server" ID="Image2"
            ImageUrl="~/Images/Calendar_icon.gif"
            ToolTip="Click the icon to show the calendar." />
        <ajaxToolkit:CalendarExtender ID="CalendarExtender2" runat="server"
            TargetControlID="TextBox3"
            Format="MM/dd/yyyy"
            FirstDayOfWeek="Monday"
            PopupButtonID="Image2">
        </ajaxToolkit:CalendarExtender>
    </InsertItemTemplate>
</asp:TemplateField>

If the blogger clicks the "Edit" link at the lower right part, the control changes into editing mode. In the editing mode (or in the insert mode), when the user clicks the calendar-shaped icon, a pop up calendar is there for him or her to click the date time. When the click action is over, newly-selected data is shown at the nearby textbox; all the update process is clearly in the asynchronous means. Figure 7 shows one of the related running-time snapshots when editing the date time of one blog.

Figure 7 - Use the AJAX Control toolkit extender CalendarExtender to enhance the user experience when editing the date time

Third, as is shown in Figure 7, there is a happy face. This just relates to our topic here. As emphasized above and still to gain a friendlier user experience, we use the AJAX Control toolkit extender ToggleButtonExtender to embroider the ASP.NET CheckBox control. In this case, a happy face (Smile.gif) corresponds to property CheckedImageUrl of control ToggleButtonExtender, while a sad face (Sad.gif) to property UncheckedImageUrl of it. Listing 6 shows the related code.

Listing 6 - The AJAX Control toolkit extender CalendarExtender related code

<asp:TemplateField HeaderText="Recommendable:" SortExpression="ST_n_iscmd">
    <EditItemTemplate>
    <asp:CheckBox ID="CheckBox1" runat="server" 
        Checked='<%# Bind("ST_n_iscmd") %>' />
        <ajaxToolkit:ToggleButtonExtender ID="ToggleButtonExtender1" 
            runat="server" TargetControlID="CheckBox1"
            CheckedImageAlternateText="Recommend" 
            CheckedImageUrl="Images/Smile.gif" ImageHeight="48"
            ImageWidth="48" UncheckedImageAlternateText="No Recommending"
            UncheckedImageUrl="Images/Sad.gif">
        </ajaxToolkit:ToggleButtonExtender>   
    </EditItemTemplate>
    <InsertItemTemplate>
    <asp:CheckBox ID="CheckBox1" runat="server" 
        Checked='<%# Bind("ST_n_iscmd") %>' />
        <ajaxToolkit:ToggleButtonExtender ID="ToggleButtonExtender2" 
            runat="server" TargetControlID="CheckBox1" 
            CheckedImageAlternateText="Recommend" 
            CheckedImageUrl="Images/Smile.gif" 
            ImageHeight="48" ImageWidth="48" 
            UncheckedImageAlternateText="No Recommending" 
            UncheckedImageUrl="Images/Sad.gif">
        </ajaxToolkit:ToggleButtonExtender> 
    </InsertItemTemplate>
    <HeaderStyle HorizontalAlign="Right" />
    <ItemTemplate>
    <asp:CheckBox ID="CheckBox1" runat="server" Checked='<%# Bind("ST_n_iscmd") %>' 
        Enabled="false" />
        <ajaxToolkit:ToggleButtonExtender ID="ToggleButtonExtender3" 
            runat="server"
            TargetControlID="CheckBox1"
            CheckedImageAlternateText="Recommend" 
            CheckedImageUrl="Images/Smile.gif"
            ImageHeight="48" ImageWidth="48" 
            UncheckedImageAlternateText="No Recommending" 
            UncheckedImageUrl="Images/Sad.gif">
        </ajaxToolkit:ToggleButtonExtender>    
    </ItemTemplate>
</asp:TemplateField>

In this case, field ST_n_iscmd in table ST_news is a Boolean type. When the value is set to true, it means the blogger recommends it to the surfers; or else, non-recommendable. In traditional ASP.NET mode, we usually use the checkbox control for the users to make the selection, while herein we use a pair of images with contrary expressions to gain the AJAX styled user experience.

Let us now shift our attention to the blog comments related programming.

Blog Comments Management - Admin_Comments.aspx

As is indicated from the menu on the left in the master page, when you click hyperlink "Comments Management" you will be navigated to page Admin_Comments.aspx. The page bears the responsibility of managing the various comments made by valid blog readers. Herein, we have simplified the design - merely performing the functionality of deleting selected comments. As the many of the other parts in this system, this page is also an Ajax based content page with an ASP.NET GridView control to display the rough comment info as well as accomplish the deleting operation. Figure 8 gives the design-time snapshot to manage blog related comments.

Figure 8

Compared with the above pages, this one is pretty simple. However, there are still three points worth noticing.

First, as is well known, the ASP.NET GridView control itself does not support deleting more than one row of data records. However, in practical scenarios this is often required so users can delete the entire selected records one time to gain a better user experience. In this case, to delete comments, the user can first check/uncheck the check boxes at the "Select" column, and then click the button "Delete selected rows" to easily remove all the selected records from the backend database. To make clearer the how-tos, Listing 7 shows the related click event handler with detailed comments.

Listing 7

protected void DeleteSelectedRows_Click(object sender, EventArgs e)
{
    //Iterate through all the GridView Rows
    foreach (GridViewRow row in GridView1.Rows)
    {
        //Get the first column from the row where the HtmlInputCheckBox is located
        TableCell cell = row.Cells[0];
 
        //Get the HtmlInputChecklBox control from the cells control collection
        HtmlInputCheckBox checkBox = cell.Controls[1] as HtmlInputCheckBox;
 
        //If the checkbox exists and are checked, execute the 
        //Delete command where the
        //value form the HtmlInputCheckBox?Value property is set 
        //as the value of the delete command parameter.
        if (checkBox != null && checkBox.Checked)
        {
            SqlDataSource1.DeleteParameters["ST_r_id"].DefaultValue = 
                checkBox.Value;
            SqlDataSource1.Delete();
        }
    }
    lbInfo.Text = "The deletion has succeeded!";
}

The second point worth noticing is that to gain better and safer user effects, when the user clicks "Delete selected rows" we first display to him or her a friendly prompt dialog to confirm the current deleting operation, as is done through the AJAX control toolkit extender ConfirmButtonExtender. Listing 8 shows the related HTML code.

Listing 8 - Using the AJAX control toolkit extender ConfirmButtonExtender to achieve the safer operation

<asp:Button ID="btnDel" runat="server" Text="Delete selected rows"  
    OnClick="DeleteSelectedRows_Click"/>
<asp:Label ID="lbInfo" runat="server" ForeColor="Red"></asp:Label>
<ajaxToolkit:ConfirmButtonExtender ID="cbe" runat="server" 
    TargetControlID="btnDel" 
    ConfirmText="Are you sure to delete all your selections?">
</ajaxToolkit:ConfirmButtonExtender>

Since the extender ConfirmButtonExtender is very easy to follow, we won’t chatter much about it.

The third and the last point is, of course, the UpdatePanel control that surrounds the one and only GridView control. As you may have guessed, when the user confirms the current deleting operation, all the comment data within the GridView control will be partially updated.

That is all for page Admin_Comments.aspx. The next page that comes up is Admin_link.aspx.

The Link Management - Admin_link.aspx

The web form Admin_link.aspx takes charge of managing all the blog host interested hyperlinks that will be shown at the left side of the home page. Figure 9 gives the related design-time snapshot.

Figure 9 - The design-time snapshot of page Admin_link.aspx

From Figure 9, you can see that the layout and design of this page is very much like those of page Admin_Comments.aspx in addition to two aspects. One dissimilar point is the appearance of an "Add" and the other is two AJAX control toolkit extender TextBoxWatermarkExtenders (which are introduced to embroider the two nearby text boxes) are utilized. As of the latter we select to omit it since the TextBoxWatermarkExtender extender has been put in use and explained in the first installment of this series.

Now let us say a few words about the "Add" button. In fact, this is also a simple and typical operation concerning the GridView control.

To make things clearer, we still give the related code.

Listing 9 - The key HTML code of page Admin_link.aspx

<script runat="server">
    void btnAdd_Click(object sender, EventArgs e)  {
        SqlDataSource1.InsertParameters["ST_l_name"].DefaultValue = 
          txtLinkName.Text;
        SqlDataSource1.InsertParameters["ST_l_url"].DefaultValue = 
          txtLinkURL.Text;
        SqlDataSource1.Insert();
    }
</script>
…… (Omitted)
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:GridView ID="GridView1" runat="server" AllowPaging="True" 
            AutoGenerateColumns="False" DataKeyNames="ST_l_id" 
            DataSourceID="SqlDataSource1">
            <Columns>
               <asp:TemplateField HeaderText="Select">
                   <ItemTemplate>
                     <input id="LinkID" type="checkbox" runat="server" 
                        value='<%# Eval("ST_l_id") %>' />
                   </ItemTemplate>
               </asp:TemplateField>
                <asp:BoundField DataField="ST_l_id" HeaderText="Link ID" 
                    InsertVisible="False" 
                    ReadOnly="True" SortExpression="ST_l_id" />
                <asp:BoundField DataField="ST_l_name" HeaderText="Link Name" 
                    SortExpression="ST_l_name" />
                <asp:BoundField DataField="ST_l_url" HeaderText="URL" 
                    SortExpression="ST_l_url" />
            </Columns>
        </asp:GridView>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="btnDel" EventName="Click" />
        <asp:AsyncPostBackTrigger ControlID="btnAdd" EventName="Click" />
    </Triggers>
</asp:UpdatePanel>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 
SelectCommand="SELECT [ST_l_id], [ST_l_name], [ST_l_url] FROM [ST_link]"
DeleteCommand="DELETE [ST_link] WHERE [ST_l_id] = @ST_l_id"
InsertCommand=
"INSERT INTO [ST_link] ([ST_l_name],[ST_l_url]) VALUES (@ST_l_name,@ST_l_url)">
            <DeleteParameters>
                 <asp:Parameter Type= "Int32" Name="ST_l_id"></asp:Parameter>
            </DeleteParameters>    
            <InsertParameters>
                <asp:Parameter Name="ST_l_id" Type="Int32" />
                <asp:Parameter Name="ST_l_name" Type="String" />
                <asp:Parameter Name="ST_l_url" Type="String" />
            </InsertParameters>                     
        </asp:SqlDataSource>
…………… (Omitted)
<asp:Button ID="btnDel" runat="server" Text="Delete selected rows"  
    OnClick="DeleteSelectedRows_Click"/>
<asp:Label ID="lbInfo" runat="server" ForeColor="Red"></asp:Label>
<cc1:ConfirmButtonExtender ID="cbe" runat="server" TargetControlID="btnDel" 
    ConfirmText="Are you sure to delete all your selections?">
</cc1:ConfirmButtonExtender>
…………… (Omitted)
<asp:Label ID="Label1" runat="server" Text="Website Name:" />
<asp:TextBox ID="txtLinkName" runat="server" />
    <br />
<asp:Label ID="Label2" runat="server" Text="Website URL:" />
<asp:TextBox ID="txtLinkURL" runat="server"></asp:TextBox>  
    <br /> 
<asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="btnAdd_Click"/> 

Note that all the deleting related operations are pretty similar to those of the previous page. When "Add" is clicked, its related click handler btnAdd_Click will be invoked. After populating all the property InsertParameters related values method, Insert of SqlDataSource1 is called. Then the adding operation is finished. As is clearly shown above, the "Add" button is set as the trigger AsyncPostBackTrigger of the UpdatePanel control, which, of course, will result in an AJAX styled updating with the GridView control (enclosed by the UpdatePanel control).

Next, let us look into the final blog host (in this case also the administrator) related management taskmanipulating the messages that are left by surfers, which is achieved through page Admin_Message.aspx.

Message Management - Admin_Message.aspx

Take a look at the design-time snapshot of page Admin_Message.aspx.

Figure 10

Well, since this page is nearly a copy of page Admin_Comments.aspx we do not have to waste words on it. You can refer to the previously narrated page Admin_Comments.aspx to follow up with it.

For now, we have finished up all the backend administrator (also in this case the blog host) related tasks.

Downloads

Brief Summary

In this installment, we have accomplished the main tasks in the mini blog system from the point of view of the backend administrator. For simplicity, we assign the same rights to both the administrator and the blog hosts. However, in practical situations this is not really the case. Because of time restraints, we have only leveraged several AJAX style related controls as well as the AJAX control toolkit extenders. In the next (and the last) installment of this series we will examine the common user related functionalities and tasks.



User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-28 4:34:45 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search