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

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

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

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

Figure 13.8 Continued

appSettings = settings.AppSettings()

connectionString = appSettings.Item("ConnectionString")

Dim connection As New OleDbConnection(connectionString) connection.Open()

Dim adapter As New OleDbDataAdapter(SQL, connection)

Dim myData As New DataSet()

adapter.Fill(myData)

adapter.Dispose()

connection.Close()

Return myData

End Function

Friend Shared Sub ExecuteNonQuery(ByVal SQL As String)

Dim connectionString As String

Dim settings As ConfigurationSettings

Dim appSettings As NameValueCollection

appSettings = settings.AppSettings()

connectionString = appSettings.Item("ConnectionString")

Dim connection As New OleDbConnection(connectionString) connection.Open()

Dim myCommand As New OleDbCommand() myCommand.Connection = connection myCommand.CommandText = SQL myCommand.CommandType = CommandType.Text myCommand.ExecuteNonQuery()

'clean up

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

581

Figure 13.8 Continued

connection.Close()

myCommand.Dispose()

connection.Dispose()

End Sub

End Class

You see that the two methods in DataControl are in fact, rather simple. As was discussed earlier in this book, these functions connect to the database and do a specific function (execute SQL scripts and one returns a DataSet).The one thing to note is that the connection string is being retrieved from the ConfigurationSettings.AppSettings.These are dynamic settings that the .NET runtime gives you access to.When you’re running an ASP.NET application, they are located in the web.config file. In another type of application, they are located in ProjectName.exe.config.That’s it for our Data object.The next step is to take a look at our User object.

Designing the User Class

When we looked at the user information when thinking about the database, we discovered a number of fields that needed to reside in the User table. Luckily all our classes will be structured in a way to nearly match the database; the User class is no exception.The only difference is that this User is a VB.NET class and not a database table.

There are four basic types of users: Guests, Registered users, Administrators, and Moderators. All of these should be represented when we build our User class. Again, you might say something like “but this is an object-oriented application, and if we have multiple types of one object, shouldn’t they be separate?” Again, you would be right.There are three types of users. All have similar properties; the only difference is that some do certain things that others can’t. For instance, a registered user in a bulletin board would have the ability to post threads and messages, whereas a guest user would not. A registered user would also have the ability to edit his or her profile and edit his or her messages, whereas a guest user would not be able to. An administrator would have the ability to do everything a registered user could, except globally. A moderator can modify posts and threads in boards he or she has moderator privileges to.

Now that we’ve identified the multiple types of users, we need to determine if we should have multiple types of users in our application. A Guest can only

www.syngress.com

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

browse a bulletin board, as no security is necessary for browsing. A Registered User can create and edit posts, and modify his or her profile. An Administrator can do anything he or she wants to the bulletin board. A Moderator can do what a Registered User can, and can act like an Administrator on the board he or she is given moderation rights to.

You may want to build some neat OO objects here, but all these things can be accomplished through a single User class.Take a look at Figure 13.9.

Figure 13.9 The User Object Diagram

User

+ID : Long

+Username : String

+Password : String

+FirstName : String

+LastName : String

+Email : String

+IsAdmin : Boolean

+IsBanned : Boolean

+Validate() : User +Update() +Create() : User

You see that our User object will have the exact same fields as our database table, which is named exactly the same.This makes it a bit easier to remember which field in the object matches up to which field in the database.The other thing you should notice is the three items down at the bottom of the diagram: Create, Validate, and Update. All are methods the User object will have. Update() will update the user’s details and save them to the database. Validate is a shared method of the User class, and can be used to perform all user validation. Create is also a shared method, and can be used to create a brand new user in the database.

That’s it.That’s the whole User object. Not much to it is there? It has a Boolean field to signify whether or not it is an administrator, and each Board object will store the ID of the administrator of that Board, so the User object doesn’t have to.The only other thing to mention is guest users—a guest user will just be a User that is Nothing.That is, if you are currently a guest in the application, you won’t have a User object created for you. Let’s take a look at the code involved to create this User object in Figure 13.10 (which can also be found on your CD called User.vb).

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

583

Figure 13.10 The Basics (User.vb)

Public Class

User

 

 

Private

mUsername As

String

Private

mPassword As

String

Private

mFirstName As String

Private

mLastName As

String

Private

mUserID

As Long

Private

mIsAdmin As

Boolean

Private

mEmail

As String

Private

mUserID

As Long

End Class

 

 

 

 

 

 

 

That part is clear enough.We declare the User class, and the private variables necessary to represent each user. Next, declare the public properties for each of these private variables as shown in Figure 13.11.

Figure 13.11 Public Properties (User.vb)

Public WriteOnly Property Password() As String

Set(ByVal Value As String)

MPassword = Value

End Set

End Property

Public ReadOnly Property ID() As Long

Get

Return mUserID

End Get

End Property

Public Property LastName() As String

Get

Return mLastName

End Get

Set(ByVal Value As String)

Continued

www.syngress.com

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

Figure 13.11 Continued

mLastName = Value

End Set

End Property

Public Property FirstName() As String

Get

Return mFirstName

End Get

Set(ByVal Value As String)

mFirstName = Value

End Set

End Property

Public Property Username() As String

Get

Return mUsername

End Get

Set(ByVal Value As String)

mUsername = Value

End Set

End Property

Public Property IsAdmin() As Boolean

Get

Return mIsAdmin

End Get

Set(ByVal Value As Boolean)

mIsAdmin = Value

End Set

End Property

Public Property IsBanned() As Boolean

Get

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

585

Figure 13.11 Continued

Return mIsBanned

End Get

Set(ByVal Value As Boolean)

mIsBanned = Value

End Set

End Property

Public Property Email() As String

Get

Return mEmail

End Get

Set(ByVal Value As String)

mEmail = Value

End Set

End Property

With that out of the way, let’s look at the methods the User object will have.As we saw earlier, there will be three methods: Validate, CreateUser, and Update. Validate is a shared method which will give a developer the ability to validate and return a valid User object, or throw an exception. CreateUser is also a shared method that gives the developer the ability to create a new User object. Finally, Update will allow a developer to update the private fields in the User object and commit them to the database.This will be for tasks like saving passwords and updating e-mail addresses. Let’s take a look at the first method, Validate, in Figure 13.12.

Figure 13.12 The Validate Method (User.vb)

Public Shared Function Validate(ByVal username As String, _ ByVal password As String) As User

If password.Equals("") Then

Throw New ArgumentException("You must enter a password.") Else

Dim myData As DataSet = DataControl.GetDataSet("SELECT * " & _ "FROM [Users] WHERE [UserName] = '" & username & "'")

If myData.Tables(0).Rows.Count <= 0 Then

Continued

www.syngress.com

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

Figure 13.12 Continued

Throw New ArgumentException("Username does not exist.")

Else

If CBool(myData.Tables(0).Rows(0)("IsBanned")) = True Then

Throw New Exception("User is banned")

Else

If password <> _

CStr(myData.Tables(0).Rows(0)("Password")) Then

Throw New ArgumentException("Invalid password")

Else

Return New User(myData.Tables(0).Rows(0))

End If

End If

End If

End If

End Function

The Validate method accepts a username and a password as parameters, and attempts to verify that those parameters are a valid combination for a registered user. If the password is empty, it throws an ArgumentException. If, while looking up the username, it finds that the username is not present in the database, it again throws an ArgumentException. If the username exists, but the user is banned, then it throws an Exception. If the username exists, the user is not banned, and the password passed in was incorrect, once again it throws an ArgumentException. Finally, if the username is valid and the password is correct, it returns a new User object, passing in the first DataRow to the User constructor.

At this point, you’re probably wondering why we haven’t discussed the constructor of the User object.Well, wait no longer! Here’s the code for the User object constructor in Figure 13.13.

Figure 13.13 Constructors (User.vb)

Public Sub New(ByVal userId As Long)

Dim myData As DataSet

myData = DataControl.GetDataSet("SELECT * FROM Users " & _

"WHERE UserID = " & Me.mUserID)

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

587

Figure 13.13 Continued

If myData.Tables(0).Rows.Count <= 0 Then

Throw New ArgumentException("The requested user " & _ does not exist.")

Else

inflate(myData.Tables(0).Rows(0)) End If

myData.Dispose() End Sub

Public Sub New(ByVal row As DataRow) inflate(row)

End Sub

There are two constructors here.The second constructor is what the Validate method called.That constructor forwards the DataRow on to another method called inflate, which will be discussed in a moment.The first constructor accepts a user ID as a parameter.This user ID is synonymous with the UserID field in the User table.The constructor looks up the user based on the user ID. If that user ID is not found, it throws an ArgumentException. If the user ID is found, it forwards the first DataRow in the DataSet to the fillData method in Figure 13.14.

Figure 13.14 The fillData Method (User.vb)

Private Sub inflate(ByVal row As DataRow)

Me.mUsername = CStr(row("Username"))

Me.mFirstName = CStr(row("FirstName"))

Me.mLastName = CStr(row("LastName"))

Me.mIsAdmin = CBool(row("IsAdmin"))

Me.mEmail = CStr(row("Email"))

Me.mUserID = CLng(row("UserID"))

Me.mPassword = CStr(row("Password"))

End Sub

www.syngress.com

588

Chapter 13 • Creating a Message Board with ADO and XML

 

 

As you can see, the inflate method accepts a DataRow as a parameter, and pop-

 

 

ulates all the private fields with values from the database.This is frequently called

 

 

“inflating” your objects, hence the appropriately named subroutine.The other

 

 

thing to notice is that inflate is a private subroutine.This is because you don’t

 

 

want any objects outside of the current User object to have access to this method.

 

 

It does “utility” work on the object, and is unnecessary for any other object to

 

 

call this method.

 

 

 

Now that we’ve discussed how to Validate and return a valid User object, let’s

 

 

move on to creating users. Any user can have any username.The only restriction

 

 

is that no two users can have the same username.This is because if you had two

 

 

users with the same username, the only way to identify which one you wanted is

 

 

to have some other sort of unique identifier. Unfortunately, people can typically

 

 

remember names and usernames much better than they could some (relatively)

 

 

random number. So, in order to keep this username unique, you have to manually

 

 

check. If you were a database administrator, you would probably insist on creating

 

 

a unique index on the username field in the database, which is completely rea-

 

 

sonable. If you feel you need the extra “security” in place to make sure the same

 

 

username isn’t taken twice, go ahead and put it in there, but it’s in the CreateUser

 

 

method as well, which we will now take a look at in Figure 13.15.

 

 

Figure 13.15 The CreateUser Method (User.vb)

 

 

 

 

 

Public Shared Function CreateUser(ByVal userName As String, _

 

 

ByVal password As String, _

 

 

ByVal firstName As String, _

 

 

ByVal lastName As String, ByVal email As String) As User

 

 

Dim

sql As String

 

 

Dim

myData As

DataSet

 

 

sql = "SELECT

userName FROM Users WHERE userName = '" & _

 

 

 

userName & "'"

 

 

myData = DataControl.GetDataSet(sql)

 

 

If myData.Tables(0).Rows.Count <= 0 Then

 

 

 

'this username has not been taken

 

 

 

sql = "INSERT INTO [Users] ([Username], [Password], " & _

"[FirstName], [LastName], " & _

Continued

www.syngress.com

Creating a Message Board with ADO and XML • Chapter 13

589

Figure 13.15 Continued

"[Email], [IsAdmin], [IsBanned]) VALUES ('" & userName & _ "','" & password & "','" & firstName & "','" & lastName & _ "','" & email & "',0,0)"

DataControl.ExecuteNonQuery(sql)

Return User.Validate(userName, password)

Else

'this username has already been taken

Throw New ArgumentException("The username is already taken") End If

End Function

First, the CreateUser function scans the database to see if the request username already exists. If it does, it throws an ArgumentException. If the username doesn’t exist, it builds a SQL statement to insert a new row into the user table and executes it. Finally it calls the Validate method and returns the result.

The last method to discuss is the Update method.This method updates the database with the current state of the object. See Figure 13.16 for the Update method.

Figure 13.16 The Update Method (User.vb)

Public Sub Update()

Dim sql As String

sql = "UPDATE [Users] SET [Password] = '" & mPassword & _ "', [FirstName] = '" & mFirstName & _

"', [LastName] = '" & mLastName & _ "', [Email] = '" & mEmail & "'"

If Me.IsAdmin = True Then

sql = sql & ", [IsAdmin] = 1"

Else

sql = sql & ", [IsAdmin] = 0" End If

If Me.IsBanned = True Then

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

Else

Continued

www.syngress.com