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

ASP .NET Web Developer s Guide - Mesbah Ahmed, Chris Garrett

.pdf
Скачиваний:
37
Добавлен:
24.05.2014
Размер:
7.32 Mб
Скачать

590 Chapter 13 • Creating a Message Board with ADO and XML

Figure 13.16 Continued

sql = sql & ", [IsBanned] = 0"

End If

sql = sql & " WHERE [UserID] = " & mUserID.ToString()

DataControl.ExecuteNonQuery(sql)

End Sub

Again, this method is rather simple. It generates a SQL statement to update the database.The If statements are there to insert the correct Boolean value into the database instead of “True” or “False.” Finally, after building the SQL statement, it executes it and exits the method.

Debugging…

Creating Console Applications to Test Your Progress

Visual Studio .NET gives us an easy way to test and debug our applications, without actually needing to have a decent User Interface to look at. They call it a Console Application. Sure, Console Applications are useful by themselves when you don’t need a UI, but when you are building a relatively large application and you don’t want to get yourself confused trying to build the UI and the classes at the same time, consider using a Console Application to debug your project.

Go ahead and try it.

1.Add a new Console Application to your project.

2.Add a reference to your dotBoardObjects project to the Console Application.

3.Set your new Console Application as the start-up project.

4.Start putting in some code to test the classes you’ve written. Maybe something like this:

Dim myUser As User

myUser = User.CreateUser("myuser", "mypassword", "joe", _

"blow", "joe.blow@email.com")

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

591

Console.WriteLine(myUser.FirstName)

Console.WriteLine("Press enter to finish")

Console.ReadLine()

Before you run this, put a break point on the line that creates a user.

5.Step through the code using F8 (if you set up your Visual Studio to use the Visual Basic Profile) and watch as the execution moves into the User class you created. You can step through your application and watch as every line of code gets executed. If an error pops up, stop your application, fix the error, and run the application again.

You should use and abuse this technique as much as possible. Not only does it allow you to test and debug your classes, but it also does it without your needing to build a UI at the same time you build the objects.

Designing the Board Class

Now that we’ve designed the User class, let’s take a look at the Board class. A lot of the concepts in the User class will be taken from the Board class.That is, the Board class will mimic the Board table in the database, and will have a couple of similarly named methods as in the User class. Let’s take a look at a UML diagram of the Board class in Figure 13.17.

Figure 13.17 The Board Class

Board

+BoardID : Long

+Name : String +Description : String +ChildThreads +ChildThread

+Update()

+CreateThread()

+Delete()

+DeleteThread()

+DeletePost() +CreateBoard() : Board

www.syngress.com

592 Chapter 13 • Creating a Message Board with ADO and XML

Just by looking at this diagram, you can see that the Board class has a lot more functionality than the User class. Notice the four fields from the Board table: BoardID, Name, and Description. Just like the User class, these are directly representative of what exists in the database.The other two fields you shouldn’t recognize. ChildThreads returns a list of the Threads that exist in this Board. ChildThread is a property that accepts a ThreadID to return a specific Thread that is directly located in a specific Board.

The methods available to a Board object should be somewhat self-explanatory. The Update method does exactly what the User class Update method did: updates the database with the private fields in the database.The Delete method deletes the Board from the database. DeleteThread deletes a specific Thread from the

database. DeletePost deletes a specific Post that is located somewhere in this Board. CreateThread creates a new Thread and adds it to the private list of Threads in this Board. Like the User class, the Board class has a way to create new Boards, called CreateBoard. Let’s start off by showing the basics of the Board class in Figure 13.18 (which can also be found on your CD under the name Board.vb).

Figure 13.18 Private Fields and Public Properties (Board.vb)

Public Class

Board

 

Private

mBoardID As

Long

Private

mName As String

Private

mDescription

As String

Private

myThreads As

ThreadList

Public ReadOnly Property ChildThread(ByVal threadId As Long) As _ Thread

Get

'lookup the correct thread Dim i As Integer

For i = 0 To Me.ChildThreads.Count - 1

Dim myThread As Thread = Me.ChildThreads.Item(i)

If myThread.ID = threadId Then

Return myThread

End If

Next i

'if we've gotten to this point, there is no thread

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

593

Figure 13.18 Continued

'with that ID in this board. throw an exception Throw New ArgumentException("Thread does not exist")

End Get

End Property

Public ReadOnly Property ChildThreads() As ThreadList

Get

Return myThreads

End Get

End Property

Public ReadOnly Property ID() As Long

Get

Return mBoardID

End Get

End Property

Public Property Name() As String

Get

Return mName

End Get

Set(ByVal Value As String)

mName = Value

End Set

End Property

Public Property Description() As String

Get

Return mDescription

End Get

Set(ByVal Value As String)

mDescription = Value

End Set

End Property

www.syngress.com

594 Chapter 13 • Creating a Message Board with ADO and XML

The public properties in this class are a little more complex than the properties in the User class.The public properties for the private fields are easy to understand, but ChildThread and ChildThreads are a bit more complex, as is the private myThread variable. Let’s start with myThread, which is defined as being of type ThreadList. If you’re familiar with the System.Collections namespace, you’ll definitely notice that this is not one of the built-in .NET collections.ThreadList is actually a custom list that wraps an ArrayList, which will be discussed a bit later. For now, just accept the fact that this list collects all the Threads in a given Board.

The ChildThreads property returns the private myThreads variable.The ChildThread property accepts a ThreadID as a parameter, and looks up that ThreadID in the myThreads list. It loops through the list, and compares the ID of the Thread in the list with the ThreadID passed in. If it finds a match, it returns that Thread, otherwise it throws an ArgumentException. Again,ThreadList will be discussed later, but for now, let’s move on to the shared CreateBoard method, as shown in Figure 13.19.

Figure 13.19 The CreateBoard Method (Board.vb)

Public Shared Function CreateBoard(ByVal name As String, _

ByVal description As String, _

ByVal creator As User) As Board

Dim sql As String

Dim myData As DataSet

If creator.IsAdmin = True Then

sql = "SELECT BoardName FROM [Board] WHERE [BoardName] = '" & _ name & "'"

myData = DataControl.GetDataSet(sql)

If myData.Tables(0).Rows.Count <= 0 Then 'this board name does not already exist.

sql = "INSERT INTO [Board] ([BoardName], " & _ "[BoardDescription], " & _

") VALUES ("

sql &= "'" & name & "','" & description & _ "')"

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

595

Figure 13.19 Continued

'create the board DataControl.ExecuteNonQuery(sql) 'return the board

Return New Board(name)

Else

'board name already exists

Throw New Exception("This board name already exists")

End If

Else

Throw New Exception("Only admins may create boards")

End If

End Function

The first step in this method is to check to see if the user that is requesting a new Board be created is an admin. If the user is not an admin, it throws an exception. If the user is an admin, it then checks to see if a Board with that name has already been created. Like the username field in the User class, the name field in the Board class should be unique.This makes it easier to manage your Boards and to make sure they’re named appropriately. If the Board name already exists, it throws an exception, otherwise it generates the SQL statement necessary to create a Board. It then executes the SQL statement and returns a new Board object based on the Board name. Let’s take a look at the Board constructor, shown in Figure 13.20, to see what it does.

Figure 13.20 Constructor (Board.vb)

Public Sub New(ByVal name As String)

Dim sql As String

Dim myData As DataSet

sql = "SELECT * FROM [Board] WHERE [BoardName] = '" & _ name & "'"

myData = DataControl.GetDataSet(sql)

If myData.Tables(0).Rows.Count > 0 Then

Me.inflate(myData.Tables(0).Rows(0))

Continued

www.syngress.com

596 Chapter 13 • Creating a Message Board with ADO and XML

Figure 13.20 Continued

Else

Throw New Exception("Board does not exist")

End If

End Sub

Private Sub inflate(ByVal myRow As DataRow) mName = CStr(myRow("BoardName"))

mDescription = CStr(myRow("BoardDescription"))

mBoardID = CLng(myRow("BoardID"))

myThreads = New ThreadList(mBoardID) End Sub

The Board constructor takes the Board name as a parameter, and looks in the database for that Board name. If it cannot find the Board, it throws an Exception, otherwise it passes the first DataRow in the DataSet to the inflate method.The inflate method functions exactly as it did in the User class: it fills up the private fields with values.The only difference here is that the myThreads variable is initialized and the BoardID is passed to it. Again, the ThreadList will be discussed a bit later, but trust that the ThreadList takes the BoardID passed in and creates a collection of the Threads in this Board. Next, let’s take a look at the Update method in Figure 13.21.

Figure 13.21 The Update Method (Board.vb)

Public Sub Update(ByVal requestor As User)

If requestor.IsAdmin Then

'update the database with this board's details Dim sql As String

sql = "UPDATE [Board] SET [BoardName] = '" & mName & _ "', BoardDescription = '" & mDescription & _

" WHERE [BoardID] = " & mBoardID.ToString()

DataControl.ExecuteNonQuery(sql)

End If

End Sub

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

597

The Update method in the Board class does exactly what the User class’s Update method did.The only real difference here is that it checks to make sure the user requesting the update is really an admin. If the user is not an admin, then it throws an exception. Next, take a look at Figure 13.22 for the CreateThread method.

Figure 13.22 The CreateThread Method (Board.vb)

Public Sub CreateThread(ByVal subject As String, _

ByVal creator As User)

Dim sql As String

sql = "INSERT INTO [Threads] ([ThreadSubject], " & _ "[CreatorID], [BoardID]) VALUES ('" & subject & _ "'," & creator.ID.ToString() & "," & _ mBoardID.ToString() & ")"

DataControl.ExecuteNonQuery(sql)

'reinitialize the thread list myThreads.InitializeThreads()

End Sub

The CreateThread method builds the SQL statement necessary to insert a new Thread into the database, and then reinitializes the private ThreadList variable by calling its InitializeThreads method.You may be wondering why the Board class has the Create method for its child objects, whereas both the User class and Board class have their Create method located in their class definitions.This is because both the User class and Board class do not have any parent-child relationships with any other classes.When you have a parent object and multiple child objects, the typical place to put the creation of the child objects is in the parent object.This is a matter of semantics— if you prefer to have your child objects create themselves, feel free to do it that way.

Let’s explore how to delete objects.The Board class contains the Delete, DeleteThread, and DeletePost methods.The Board class can obviously delete itself, but why would it also contain the ability to delete both threads and posts? It has these two methods because the Board class is where the ModeratorID lives, and Moderators can delete both threads and posts, so it just seems natural to put these two delete methods in the Board class. Look at Figure 13.23 for the code.

www.syngress.com

598 Chapter 13 • Creating a Message Board with ADO and XML

Figure 13.23 The Delete Method (Board.vb)

Public Sub Delete(ByVal requestor As User) 'only admins can delete boards

If requestor.IsAdmin Then

Dim sql As String

sql = "DELETE FROM Boards WHERE BoardID = " & _ mBoardID.ToString()

DataControl.ExecuteNonQuery(sql)

Else

Throw New ArgumentException("User not permitted to delete") End If

End Sub

The first step in the Delete method is to check to make sure the requesting user has the appropriate access rights to delete this board. If the user is not an admin, then an ArgumentException is thrown. If the user does have access rights to delete a Board, then the SQL statement is built to delete the Board from the database.The SQL statement is executed, and the Board is officially deleted.You can see the DeleteThread method in Figure 13.24.

Figure 13.24 The DeleteThread Method (Board.vb)

Public Sub DeleteThread(ByVal thread As Thread, ByVal requestor As User)

If requestor.IsAdmin Then

Dim sql As String

sql = "DELETE FROM Threads WHERE ThreadID = " & _ thread.ID.ToString()

DataControl.ExecuteNonQuery(sql) 'reinitialize the threads myThreads.InitializeThreads()

Else

Throw New ArgumentException("User not permitted to delete") End If

End Sub

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

599

The first step in the DeleteThread method is to make sure the requesting user has the appropriate access to delete this thread. If the user is neither an admin nor a moderator of this Board, then an ArgumentException is thrown. If the user does have access to delete a thread, then the SQL statement is built to delete the thread from the database.The SQL statement is executed, and the ThreadList is reinitialized by calling its InitializeThreads method.

The next method we need is the DeletePost method.Take a look at Figure 13.25 for its implementation.

Figure 13.25 The DeletePost Method (Board.vb)

Public Sub DeletePost(ByVal thread As Thread, ByVal post As Post, _ ByVal requestor As User)

If requestor.IsAdmin Then

Dim sql As String

sql = "DELETE FROM Posts WHERE PostID = " & _ post.ID.ToString()

DataControl.ExecuteNonQuery(sql) 'reinitialize the posts in the thread thread.ChildPosts.InitializePosts()

Else

Throw New ArgumentException("User not permitted to delete") End If

End Sub

Just as in the DeleteThread method, the first step in the DeletePost method is to make sure the requesting user has the appropriate access rights to delete this post. If the user is neither an admin nor a moderator of this Board, then an ArgumentException is thrown. If the user does have access to delete a post, then the SQL statement is built to delete the post from the database.The SQL statement is executed, and the Threads ChildPosts property is reinitialized by calling its

InitializePosts method.

Designing the ThreadList Class

We promised you that we would discuss the ThreadList, and here it is. As was mentioned earlier, the ThreadList class is a class that wraps an ArrayList. By wraps,

www.syngress.com