Here is the code for the Donation site with comments. First the web form. There are no changes here:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<p>Enter your information</p>
<asp:Table ID="Table1" runat="server" Width="248px">
<asp:TableRow>
<asp:TableCell>Last Name</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtLastName" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>First Name</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>Address</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtAddress" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>City</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>State</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtState" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>Zip code</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtZipcode" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>Home Phone</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtHomePhone" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>Email</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtEmail" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>Donation Amount</asp:TableCell>
<asp:TableCell>
<asp:TextBox ID="txtDonation" runat="server"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell> </asp:TableCell>
<asp:TableCell>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</div>
</form>
</body>
</html>
Here is the code for Default.aspx.vb
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
Try
Dim dude As New Person
dude.PersonFirstName = txtFirstName.Text
dude.PersonLastName = txtLastName.Text
dude.PersonAddress = txtAddress.Text
dude.PersonCity = txtCity.Text
dude.PersonState = txtState.Text
dude.PersonZipcode = txtZipcode.Text
dude.PersonHomePhone = txtDonation.Text
dude.PersonEmail = txtEmail.Text
Dim gift As New Donation
gift.DonationDate = DateTime.Now
gift.DonationAmount = Double.Parse(txtDonation.Text)
Dim data As New DataLayer(dude, gift)
Response.Write("thanks for the donation")
Catch ex As Exception
Response.Write(ex.Message)
End Try
End Sub
End Class
Now here is the Person class--no changes here:
Imports Microsoft.VisualBasic
'*****************************************
'This class ecnapsulates a person, including
'the address and contacts
'it consists only of fields (private class
'variables and properties that expose those
'variables to other classes
'****************************************
Public Class Person
'private class level variables (fields)
Private firstName As String
Private lastName As String
Private address As String
Private city As String
Private state As String
Private zipcode As String
Private homePhone As String
Private email As String
Private PKey As Integer
'public properties
Public Property PersonFirstName() As String
Get
Return FirstName
End Get
Set(ByVal value As String)
FirstName = value
End Set
End Property
Public Property PersonLastName() As String
Get
Return LastName
End Get
Set(ByVal value As String)
LastName = value
End Set
End Property
Public Property PersonAddress() As String
Get
Return address
End Get
Set(ByVal value As String)
address = value
End Set
End Property
Public Property PersonCity() As String
Get
Return city
End Get
Set(ByVal value As String)
city = value
End Set
End Property
Public Property PersonState() As String
Get
Return state
End Get
Set(ByVal value As String)
'in this porpery I validated the input
'if it is longer than 2 characters
'throw an error message back
'to the calling method
If value.Length > 2 Then
Dim ex As New Exception("use two letters for a state")
Throw ex
Else
state = value
End If
End Set
End Property
Public Property PersonZipcode() As String
Get
Return zipcode
End Get
Set(ByVal value As String)
zipcode = value
End Set
End Property
Public Property PersonHomePhone() As String
Get
Return homePhone
End Get
Set(ByVal value As String)
homePhone = value
End Set
End Property
Public Property PersonEmail() As String
Get
Return email
End Get
Set(ByVal value As String)
email = value
End Set
End Property
Public Property PersonKey() As Integer
Get
Return PKey
End Get
Set(ByVal value As Integer)
PKey = value
End Set
End Property
End Class
Here is the donation class--also no changes
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
'**************************************
'this class encapsulates a donation
'it consists of three fields and
'three properties
'*************************************
Public Class Donation
Private amount As Double
Private donDate As Date
Private Pkey As Integer
Public Property DonationAmount() As Double
Get
Return amount
End Get
Set(ByVal value As Double)
amount = value
End Set
End Property
Public Property DonationDate() As Date
Get
Return donDate
End Get
Set(ByVal value As Date)
donDate = value
End Set
End Property
Public Property DonationPersonKey() As Integer
Get
Return Pkey
End Get
Set(ByVal value As Integer)
Pkey = value
End Set
End Property
End Class
Here is the datalayer class. The one thing that has changed is the WriteDonation method is called in the constructor. As noted in the previous post, this is where the error was.
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
Imports System.Data 'import generic data objects
Imports System.Data.SqlClient 'import sql server specific objects
Public Class DataLayer
Private pers As Person
Private don As Donation
Private connect As SqlConnection
Public Sub New(ByRef p As Person, ByRef d As Donation)
'assign the passed objects to the internal fields
pers = p
don = d
'instantiate the sqlconnection string to enable
'connections to the database
connect = New SqlConnection("Data source=.\sqlexpress;initial catalog=communityAssist;integrated security=true;")
'call the method that actually writes the data
writeDonation()
End Sub
Sub writeDonation()
'*******************************************
'this method takes the values stored in the
'person and donation objects and writes them
'to the database. If you are clever you could
'break this method into smaller methods
'each of which does just one thing
'here we did it together so the pattern is
'cleare
'*******************************************
'this will insert into person
'first set up the sql insert statement. the @last, etc are
'sql variables
Dim PersonSql As String = "Insert into Person(lastName, Firstname) Values(@last, @first)"
'instantiate the command object and pass the sql and connection to its constructor
Dim personCommand As New SqlCommand(PersonSql, connect)
'Create parameters to store and assign values to the variables in the sql script
personCommand.Parameters.AddWithValue("@Last", pers.PersonLastName)
personCommand.Parameters.AddWithValue("@first", pers.PersonFirstName)
'will get the new PersonKey
'the @@identiy is a built in SQL Server variable
'that returns the last identity (autonumber)
'generated by the server--this will be the personkey
'from the person table where we just inserted a record
'we need the personkey to tie the address,
'contact information, and donation to the person
Dim personKeySql As String = "Select @@identity"
Dim personKeyCommand As New SqlCommand(personKeySql, connect)
'inserts into PersonAddress
Dim addressSQL As String = "Insert into PersonAddress(street, city, state, zip, personKey) Values(@street, @city, @state,@zip, @personKey)"
Dim addressCommand As New SqlCommand(addressSQL, connect)
addressCommand.Parameters.AddWithValue("@street", pers.PersonAddress)
addressCommand.Parameters.AddWithValue("@City", pers.PersonCity)
addressCommand.Parameters.AddWithValue("@state", pers.PersonState)
addressCommand.Parameters.AddWithValue("@zip", pers.PersonZipcode)
addressCommand.Parameters.Add("@PersonKey", SqlDbType.Int)
'insert into contact for home phone
Dim homePhoneSql As String = "Insert into PersonContact(ContactInfo, personKey, contactTypeKey)Values(@ContactInfo, @personKey, 1)"
Dim homephoneCommand As New SqlCommand(homePhoneSql, connect)
homephoneCommand.Parameters.AddWithValue("@ContactInfo", pers.PersonHomePhone)
homephoneCommand.Parameters.Add("@PersonKey", SqlDbType.Int)
'inserts into contact for email
Dim emailsql As String = "Insert into PersonContact(ContactInfo, personKey, contactTypeKey)Values(@ContactInfo, @personKey, 6)"
Dim emailCommand As New SqlCommand(emailsql, connect)
emailCommand.Parameters.AddWithValue("@ContactInfo", pers.PersonEmail)
emailCommand.Parameters.Add("@PersonKey", SqlDbType.Int)
'inserts into donation
Dim donationSql As String = "insert into donation(donationdate, donationamount,Personkey)Values(@date, @amount, @PersonKey)"
Dim donationCommand As New SqlCommand(donationSql, connect)
donationCommand.Parameters.AddWithValue("@Date", don.DonationDate)
donationCommand.Parameters.AddWithValue("@Amount", don.DonationAmount)
donationCommand.Parameters.Add("@PersonKey", SqlDbType.Int)
'now that everything is set up we will open
'the connection to the database.
'if there are any problems with the connection string
'the error will fall here
connect.Open()
Dim pk As Integer 'to store the personKey
'the transaction object is used to group
'all the statements into one thing
'either all of them happen or none
'of them happen
Dim tran As SqlTransaction
tran = connect.BeginTransaction
'here we assign the new transaction
'to all the sqlcommands
personCommand.Transaction = tran
personKeyCommand.Transaction = tran
addressCommand.Transaction = tran
homephoneCommand.Transaction = tran
emailCommand.Transaction = tran
donationCommand.Transaction = tran
'try the following code and catch any errors
Try
'first we insert the person
'ExecuteNonQuery is for any command
'that doesn't return results
personCommand.ExecuteNonQuery()
'now we get the person key. ExecuteScaler
'is used for queries that will return only
'a single value. the result an integer
'so we cast it CInt to an integer
pk = CInt(personKeyCommand.ExecuteScalar)
'Now we assign the value of personkey
'to the parameters of the
'various commands
addressCommand.Parameters("@PersonKey").Value = pk
homephoneCommand.Parameters("@PersonKey").Value = pk
emailCommand.Parameters("@PersonKey").Value = pk
donationCommand.Parameters("@PersonKey").Value = pk
'Now we execute each of the remaining commands
addressCommand.ExecuteNonQuery()
homephoneCommand.ExecuteNonQuery()
emailCommand.ExecuteNonQuery()
donationCommand.ExecuteNonQuery()
'if we don't have an error by now
'commit them all
tran.Commit()
Catch ex As Exception
'if there is an error undo it all
tran.Rollback()
'throw the error back to the form
Throw ex
Finally
'no matter what, close the connections
connect.Close()
End Try
End Sub
End Class
It all works on my machine
No comments:
Post a Comment