Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP.NET 2.0 Everyday Apps For Dummies (2006)

.pdf
Скачиваний:
60
Добавлен:
17.08.2013
Размер:
10.07 Mб
Скачать

Chapter 10: Building a Web Forum 347

EventArgs e)

 

{

 

string con = WebConfigurationManager

5

.ConnectionStrings[“ForumConnectionString”]

.ConnectionString;

 

ds = new DataSet();

6

// fill the Forums table

7

string sel = “SELECT [forumid], [name] “

 

+ “FROM Forums “

 

+ “ORDER BY [name]”;

 

SqlDataAdapter da = new SqlDataAdapter(sel, con);

da.Fill(ds, “Forums”);

 

// fill the Topics table

8

sel = “SELECT [forumid], [topicid], “

 

+ “[name], [description] “

 

+ “FROM Topics “

 

+ “ORDER BY [name]”;

 

da = new SqlDataAdapter(sel, con);

 

da.Fill(ds, “Topics”);

 

// bind the Forum repeater

9

ForumRepeater.DataSource = ds.Tables[“Forums”]

 

.DefaultView;

 

ForumRepeater.DataBind();

 

}

 

public void ForumRepeater_ItemDataBound(

10

Object sender, RepeaterItemEventArgs e)

 

{

 

Repeater r = ((Repeater)e.Item

11

.FindControl(“TopicRepeater”));

 

DataRowView drv

12

= (DataRowView)e.Item.DataItem;

 

string forumid = drv[“forumid”].ToString();

 

DataView dv

13

= ds.Tables[“Topics”].DefaultView;

 

dv.RowFilter = “forumid=” + forumid;

 

r.DataSource = dv;

14

r.DataBind();

 

}

 

}

348 Part V: Building Community Applications

Here’s a set of 14 explanations, matched to the 14 key lines of this listing:

1 The code-behind file needs access to the System.Web. Configuration namespace because it uses the WebConfigurationManager class to retrieve the database connection string from the web.config file.

2 The System.Data.SqlClient namespace is required to use ADO.NET classes such as DataSet, SqlConnection, and

SqlCommand.

3 This line defines a class instance variable of type DataSet. That way, the dataset will be available to both of the methods in the code-behind file.

4 The Page_Load method executes when the page loads. It fills the dataset with data retrieved from the Forums and Topics tables; it also sets up data binding for the ForumRepeater control and calls that control’s DataBind method, which completes the binding.

5 This line retrieves the connection string from the web.config file.

6 This statement creates an empty dataset object and assigns it to the ds variable.

7 These lines create a table in the ds dataset named Forums by a) creating a data adapter that retrieves rows from the Forums table and b) calling the data adapter’s Fill method.

8 These lines create a second table in the dataset (named Topics) by creating a data adapter (which retrieves data from this new Topics table) and calling the data adapter’s Fill method.

9 These lines set the data source for the ForumRepeater control to the Forums table in the dataset, and then call the DataBind method to bind the Repeater control to its data.

10 This method is called each time an item is bound to the outer Repeater. It binds the inner Repeater control to the topics that are associated with the forum represented by the item.

11 The e argument includes a property named Item that represents the item being bound. This statement calls that item’s FindControl method to find the Repeater control named TopicRepeater. That particular Repeater is then assigned to the variable named r so it can be used later.

12 These lines retrieve the id of the forum represented by the current Repeater item. First, e.Item.DataItem is used to retrieve a DataRowView object that lets you access the individual data fields for the Repeater item. Then the forumid field is retrieved and saved in a local variable named forumid.

Chapter 10: Building a Web Forum 349

13 These lines retrieve a DataView object for the Topics table of the data set and set its row filter so it views only those rows whose forumid field matches the value of the forumid variable.

14 These lines bind the Repeater control to the data view. This causes the Repeater control to create a line for each topic that’s associated with the forum.

Listing 10-5: The code-behind file for the home page (VB version)

Imports

System.Web.Configuration

1

Imports

System.Data.SqlClient

2

Imports

System.Data

 

Partial Class _Default

 

Inherits System.Web.UI.Page

 

Private ds As DataSet

3

Protected Sub Page_Load( _

4

 

ByVal sender As Object, _

 

 

ByVal e As System.EventArgs) _

 

 

Handles Me.Load

 

 

Dim con As String _

5

 

= WebConfigurationManager _

 

 

.ConnectionStrings(“ForumConnectionString”) _

 

.ConnectionString

 

 

ds = New DataSet()

6

 

‘fill the Forums table

7

 

Dim sel As String _

 

 

= “SELECT [forumid], [name] “ _

 

 

+ “FROM Forums “ _

 

 

+ “ORDER BY [name]”

 

 

Dim da As SqlDataAdapter _

 

 

= New SqlDataAdapter(sel, con)

 

 

da.Fill(ds, “Forums”)

 

 

‘fill the Topics table

8

 

sel = “SELECT [forumid], [topicid], “ _

 

 

+ “[name], [description] “ _

 

 

+ “FROM Topics “ _

 

 

+ “ORDER BY [name]”

 

 

da = New SqlDataAdapter(sel, con)

 

 

da.Fill(ds, “Topics”)

 

 

‘bind the Forum repeater

9

 

ForumRepeater.DataSource = ds.Tables(“Forums”) _

 

.DefaultView

 

 

ForumRepeater.DataBind()

 

End Sub

 

 

 

 

(continued)

350 Part V: Building Community Applications

Listing 10-5 (continued)

Protected Sub ForumRepeater_ItemDataBound( _

10

ByVal sender As Object, _

 

ByVal e As RepeaterItemEventArgs) _

 

Handles ForumRepeater.ItemDataBound

 

Dim r As Repeater

11

r = e.Item.FindControl(“TopicRepeater”)

 

Dim drv As DataRowView

12

drv = e.Item.DataItem

 

Dim forumid As String = drv(“forumid”)

 

Dim dv As DataView

13

dv = ds.Tables(“Topics”).DefaultView

 

dv.RowFilter = “forumid=” + forumid

 

r.DataSource = dv

14

r.DataBind()

 

End Sub

End Class

Building the Threads Page

The Threads page displays all threads for the topic selected by the user. The Threads page knows which topic to display because the topic is passed as a query string field from the Default.aspx page. Then the Threads page uses a simple GridView control bound to a SqlDataSource to retrieve and display the threads.

A code-behind file is required to handle the Click event raised by the Start a New Thread link or the SelectedItemChanged event raised by the

GridView control.

The Threads.aspx page

Listing 10-6 presents the .aspx code for the Threads page. There’s nothing unusual about the code for this page, so you shouldn’t have much trouble following it.

Listing 10-6: The Threads.aspx page

<%@ Page Language=”C#”

1

MasterPageFile=”~/MasterPage.master”

AutoEventWireup=”true”

CodeFile=”Threads.aspx.cs”

Inherits=”Threads”

Chapter 10: Building a Web Forum 351

Title=”Topic Threads” %>

2

<asp:Content ID=”Content1” Runat=”Server”

ContentPlaceHolderID=”ContentPlaceHolder1” >

3

<asp:FormView ID=”FormView1” runat=”server”

DataSourceID=”SqlDataSource1”>

 

<ItemTemplate>

 

<h2>

 

<asp:Label ID=”nameLabel” runat=”server”

Text=’<%# Bind(“name”) %>’ />

 

</h2>

 

<h3>

 

<asp:Label ID=”descriptionLabel”

 

runat=”server”

 

Text=’<%# Bind(“description”) %>’ />

</h3>

 

</ItemTemplate>

 

</asp:FormView>

4

<asp:SqlDataSource ID=”SqlDataSource1”

runat=”server”

 

ConnectionString=”<%$ ConnectionStrings

 

:ForumConnectionString %>”

 

SelectCommand=”SELECT [name], [description]

 

FROM [Topics] WHERE ([topicid] = @topicid)”>

<SelectParameters>

5

<asp:QueryStringParameter

Name=”topicid”

 

QueryStringField=”topic”

 

Type=”Int32” />

 

</SelectParameters>

 

</asp:SqlDataSource>

 

<br />

6

<asp:GridView ID=”GridView1” runat=”server”

AutoGenerateColumns=”False”

 

DataSourceID=”SqlDataSource2”

 

DataKeyNames=”threadid”

 

AllowPaging=”True”

 

PageSize=”15”

 

PagerSettings-Mode=”NumericFirstLast”

 

OnSelectedIndexChanged

 

=”GridView1_SelectedIndexChanged”>

 

<Columns>

7

<asp:ButtonField

CommandName=”Select”

 

DataTextField=”subject”

 

HeaderText=”Subject”

 

Text=”Button”>

 

<ItemStyle HorizontalAlign=”Left”

 

Width=”250px” />

 

<HeaderStyle HorizontalAlign=”Left” />

 

</asp:ButtonField>

8

<asp:BoundField

DataField=”author”

 

HeaderText=”Author” >

 

 

 

(continued)

352 Part V: Building Community Applications

Listing 10-6 (continued)

<HeaderStyle HorizontalAlign=”Left” />

 

<ItemStyle Width=”100px” />

 

</asp:BoundField>

 

<asp:BoundField

9

DataField=”replies”

 

HeaderText=”Replies” >

 

<HeaderStyle HorizontalAlign=”Center” />

<ItemStyle HorizontalAlign=”Center”

 

Width=”70px” />

 

</asp:BoundField>

 

<asp:BoundField

10

DataField=”lastpostdate”

 

HeaderText=”Last Post”

 

DataFormatString=”{0:d}” >

 

<HeaderStyle HorizontalAlign=”Center” />

<ItemStyle Width=”70px” />

 

</asp:BoundField>

 

</Columns>

 

</asp:GridView>

 

<asp:SqlDataSource ID=”SqlDataSource2”

11

runat=”server”

 

ConnectionString=”<%$ ConnectionStrings

 

:ForumConnectionString %>”

 

SelectCommand=”SELECT [threadid], [topicid],

 

[subject], [replies], [author], [lastpostdate]

FROM [Threads]

 

WHERE ([topicid] = @topicid)

 

ORDER BY [lastpostdate]”>

 

<SelectParameters>

 

<asp:QueryStringParameter

12

Name=”topicid”

 

QueryStringField=”topic”

 

Type=”Int32” />

 

</SelectParameters>

 

</asp:SqlDataSource>

 

<br />

 

<asp:LinkButton ID=”LinkButton1”

13

runat=”server”

 

Text=”Start a New Thread”

 

OnClick=”LinkButton1_Click” />

 

<br /><br />

 

<asp:LinkButton ID=”btnReturn”

14

runat=”server”

 

PostBackUrl=”~/Default.aspx”

 

Text=”Return to Forum Page” />

 

</asp:Content>

 

This listing has 14 key points to explain:

 

1 If you use the Visual Basic version of the code-behind file, be sure to change the Language, AutoEventWireup, and CodeFile attributes in the Page directive.

Chapter 10: Building a Web Forum 353

2 The <Content> element provides the content that’s displayed for the page.

3 This FormView control displays the topic name and description. It’s bound to the data source named SqlDataSource1.

4 The SqlDataSource1 data source retrieves the topic information from the Topics row, using the topicid parameter to specify the topic to be retrieved.

5 The value of the topicid parameter is bound to the query string named topic.

6 The GridView control displays the threads for the selected topic.

It’s bound to the SqlDataSource2 data source, and paging is enabled. Note that the GridView1_SelectedIndexChanged method is called if the user selects a thread.

If you’re working with Visual Basic, remove the

OnSelectedIndexChanged attribute.

7 The first column for the GridView control is a button field that displays the thread subject. The CommandName attribute specifies Select, so the row is selected when the user clicks this link.

8 The next column displays the e-mail address of the user that initially started the thread.

9 This column displays the number of replies to the thread.

10 This column displays the date of the last message posted to the thread.

11 The SqlDataSource2 data source provides the data for the GridView control. Its SelectCommand attribute specifies a SELECT statement that retrieves threads for the topic specified by the topicid parameter.

12 The topicid parameter is bound to the topic query string field.

13 This LinkButton control lets the user start a new thread.

If you’re using Visual Basic, you should omit the OnClick attribute.

14 This LinkButton sends the user back to the Forum Home page.

The code-behind file for the Threads page

The code-behind file for the Threads page handles the Click event for the Start a New Thread link and the SelectedIndexChanged event for the GridView control. Listings 10-7 and 10-8 show the C# and Visual Basic versions of this code-behind file.

354 Part V: Building Community Applications

Listing 10-7: The code-behind file for the Threads page (C# version)

using System; using System.Data;

using System.Configuration; using System.Collections; using System.Web;

using System.Web.Security; using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;

public partial class Threads : System.Web.UI.Page

 

{

 

protected void LinkButton1_Click(object sender,

1

EventArgs e)

 

{

 

Response.Redirect(“NewThread.aspx?topic=”

 

+ Request.QueryString[“topic”]);

 

}

 

protected void GridView1_SelectedIndexChanged(

2

object sender, EventArgs e)

 

{

 

string threadid

= GridView1.SelectedValue.ToString(); string topicid = Request.QueryString[“topic”];

Response.Redirect(“Messages.aspx?topic=” + topicid + “&thread=” + threadid);

}

}

The two methods in this code-behind file are the heart of how it works:

1 The LinkButton1_Click method is called when the user clicks the Start a New Thread link. It simply redirects to the NewThread.aspx page, passing the topic query string so the New Thread page knows which topic to create the thread in.

2 The GridView1_SelectedIndexChanged method is called when the user selects a thread in the GridView control. It retrieves the thread ID from the GridView control’s SelectedValue property and the topic ID from the topic query string field, then redirects to the Messages.aspx page, passing the thread and topic IDs as query string fields.

Chapter 10: Building a Web Forum 355

Listing 10-8: The code-behind file for the Threads page (VB version)

Partial Class Threads

Inherits System.Web.UI.Page

Protected Sub

LinkButton1_Click( _

1

ByVal

sender As Object, _

 

ByVal e As System.EventArgs) _

 

Handles LinkButton1.Click

 

Response.Redirect(“NewThread.aspx?topic=” _

 

+ Request.QueryString(“topic”))

 

End Sub

 

 

Protected Sub GridView1_SelectedIndexChanged( _

2

ByVal sender As Object, _ ByVal e As System.EventArgs) _

Handles GridView1.SelectedIndexChanged Dim threadid As String

Dim topicid As String

threadid = GridView1.SelectedValue.ToString() topicid = Request.QueryString(“topic”) Response.Redirect(“Messages.aspx?topic=” _

+ topicid _

+ “&thread=” + threadid)

End Sub End Class

Building the Messages Page

The Messages page displays all messages for the thread selected by the user. The thread to be displayed is passed to the Messages page as a query string named thread. In response, the Messages page uses a GridView control to display the messages.

The Messages.aspx page

Listing 10-9 presents the Messages.apsx file. As you can see, this page uses three SQL data sources, two FormView controls, and a GridView control to display the messages for the selected topic.

356 Part V: Building Community Applications

Listing 10-9: The Messages.aspx page

<%@ Page Language=”C#” MasterPageFile=”~/MasterPage.master” AutoEventWireup=”true” CodeFile=”Messages.aspx.cs” Inherits=”Messages” Title=”Messages” %>

<asp:Content ID=”Content1” Runat=”Server” ContentPlaceHolderID=”ContentPlaceHolder1” >

<asp:FormView ID=”FormView1” runat=”server” DataSourceID=”SqlDataSource1”> <ItemTemplate>

<h3>

Topic:

<asp:Label ID=”topicNameLabel” runat=”server”

Text=’<%# Bind(“name”) %>’ />

</h3>

</ItemTemplate>

</asp:FormView>

<asp:SqlDataSource ID=”SqlDataSource1” runat=”server”

ConnectionString

=”<%$ ConnectionStrings:ForumConnectionString %>”

SelectCommand=”SELECT [name], [description] FROM [Topics]

WHERE ([topicid] = @topicid)”> <SelectParameters>

<asp:QueryStringParameter

Name=”topicid”

QueryStringField=”topic” Type=”Int32” />

</SelectParameters>

</asp:SqlDataSource>

<asp:FormView ID=”FormView2” runat=”server” DataSourceID=”SqlDataSource2”> <ItemTemplate>

<h3>

Thread:

<asp:Label ID=”threadNameLabel” runat=”server”

Text=’<%# Bind(“subject”) %>’ />

</h3>

</ItemTemplate>

</asp:FormView>

<asp:SqlDataSource ID=”SqlDataSource2” runat=”server”

ConnectionString

1

2

3

4

5

6

7