You are on page 1of 19

Introduction

3-Tier architecture generally contains UI or Presentation Layer, Business Access


Layer (BAL) or Business Logic Layer and Data Access Layer (DAL).

Presentation Layer (UI)


Presentation layer cotains pages like .aspx or windows form where data is presented
to the user or input is taken from the user.

Business Access Layer (BAL) or Business Logic Layer


BAL contains business logic, validations or calculations related with the data, if
needed. I will call it Business Access Layer in my demo.

Data Access Layer (DAL)


DAL contains methods that helps business layer to connect the data and perform
required action, might be returning data or manipulating data (insert, update, delete
etc). For this demo application, I have taken a very simple example. I am assuming
that I have to play with record of persons (FirstName, LastName, Age) and I will
refer only these data through out this article.

Designing 3-Tier Architecture


For the ease of understanding, I have created BAL, DAL into the App_Code
folder. In real scenario, you should create separate projects for BAL, DAL
(as Class Library) and UI (as Web project) and reference your BAL into UI.

Data Access Layer


Lets proceed with desiging 3-Tier architecture. To do that lets proceed with DAL, BAL
and then UI. Add a class named by right clicking App_Code folder. (In my case I
have a 3-Tier folder inside App_Code folder, you can directly add inside App_Code or
you can create a separate project for DAL and add reference of this project into your
BAL.) and copy-paste folowing code (Your can overwrite your default written code for
the class file by pasting this code). Here, I have assumed that you will create
the respective stored procedure yourself into the database or you may
download attachment from
http://www.dotnetfunda.com/articles/article18.aspx article and look for
App_Data folder for complete database structure and stored procedure for
this article.

Data Access Layer (DAL)


Code for Data Access Layer

using System;

using System.Data;

using System.Configuration;
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;

using System.Data.SqlClient;

/// <summary>

/// Summary description for PersonDAL3

/// </summary>

public class PersonDAL3

string connStr =
ConfigurationManager.ConnectionStrings["TutTestConn"].ToString();

public PersonDAL3()

/// <summary>

/// Used to insert records into database

/// </summary>

/// <param name="firstName"></param>

/// <param name="lastName"></param>

/// <param name="age"></param>

/// <returns></returns>

public int Insert(string firstName, string lastName, int age)

{
SqlConnection conn = new SqlConnection(connStr);

conn.Open();

SqlCommand dCmd = new SqlCommand("InsertData", conn);

dCmd.CommandType = CommandType.StoredProcedure;

try

dCmd.Parameters.AddWithValue("@firstName", firstName);

dCmd.Parameters.AddWithValue("@lastName", lastName);

dCmd.Parameters.AddWithValue("@age", age);

return dCmd.ExecuteNonQuery();

catch

throw;

finally

dCmd.Dispose();

conn.Close();

conn.Dispose();

/// <summary>

/// Update record into database

/// </summary>

/// <param name="personID"></param>

/// <param name="firstName"></param>

/// <param name="lastName"></param>


/// <param name="age"></param>

/// <returns></returns>

public int Update(int personID, string firstName, string lastName, int


age)

SqlConnection conn = new SqlConnection(connStr);

conn.Open();

SqlCommand dCmd = new SqlCommand("UpdateData", conn);

dCmd.CommandType = CommandType.StoredProcedure;

try

dCmd.Parameters.AddWithValue("@firstName", firstName);

dCmd.Parameters.AddWithValue("@lastName", lastName);

dCmd.Parameters.AddWithValue("@age", age);

dCmd.Parameters.AddWithValue("@personID", personID);

return dCmd.ExecuteNonQuery();

catch

throw;

finally

dCmd.Dispose();

conn.Close();

conn.Dispose();

/// <summary>

/// Load all records from database


/// </summary>

/// <returns></returns>

public DataTable Load()

SqlConnection conn = new SqlConnection(connStr);

SqlDataAdapter dAd = new SqlDataAdapter("LoadAll", conn);

dAd.SelectCommand.CommandType = CommandType.StoredProcedure;

DataSet dSet = new DataSet();

try

dAd.Fill(dSet, "PersonTable");

return dSet.Tables["PersonTable"];

catch

throw;

finally

dSet.Dispose();

dAd.Dispose();

conn.Close();

conn.Dispose();

/// <summary>

/// Delete record from database

/// </summary>

/// <param name="personID"></param>


/// <returns></returns>

public int Delete(int personID)

SqlConnection conn = new SqlConnection(connStr);

conn.Open();

SqlCommand dCmd = new SqlCommand("DeleteData", conn);

dCmd.CommandType = CommandType.StoredProcedure;

try

dCmd.Parameters.AddWithValue("@personID", personID);

return dCmd.ExecuteNonQuery();

catch

throw;

finally

dCmd.Dispose();

conn.Close();

conn.Dispose();

In the above code, I have a member variable called connStr that is getting database
connection string from my web.config file that is being used through out the class. I
have separate method for inserting, deleting, updating records into database and
loading records from database. I am not goint into details of how I am connecting
database and manipulating the data just to make this tutorials short.

Business Access Layer (BAL)


Now, create a class named PersonBAL3 into App_Code folder by right clicking it and
write respective methods for calling Insert, Delete, Update and Load methods of
Data Access Layer class file (PersonDAL3) (In my case I have a 3-Tier folder inside
App_Code folder, you can directly add inside App_Code or you can create a separate
project for BAL and add reference of this project into your Presentation Layer). As we
don't have any business logic here so simply instantiate the PersonDAL3 class of DAL
and call methods. Below is the code for BAL (Your can overwrite your default written
code for the class file by pasting this code).

Code for Business Access Layer

using System;

using System.Data;

using System.Configuration;

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;

/// <summary>

/// Summary description for PersonBAL3

/// </summary>

public class PersonBAL3

public PersonBAL3()

/// <summary>

/// insert records into database

/// </summary>

/// <param name="firstName"></param>


/// <param name="lastName"></param>

/// <param name="age"></param>

/// <returns></returns>

public int Insert(string firstName, string lastName, int age)

PersonDAL3 pDAL = new PersonDAL3();

try

return pDAL.Insert(firstName, lastName, age);

catch

throw;

finally

pDAL = null;

/// <summary>

/// Update records into database

/// </summary>

/// <param name="personID"></param>

/// <param name="firstName"></param>

/// <param name="lastName"></param>

/// <param name="age"></param>

/// <returns></returns>

public int Update(int personID, string firstName, string lastName, int


age)

{
PersonDAL3 pDAL = new PersonDAL3();

try

return pDAL.Update(personID, firstName, lastName, age);

catch

throw;

finally

pDAL = null;

/// <summary>

/// Load records from database

/// </summary>

/// <returns></returns>

public DataTable Load()

PersonDAL3 pDAL = new PersonDAL3();

try

return pDAL.Load();

catch

throw;

}
finally

pDAL = null;

/// <summary>

/// Delete record from database

/// </summary>

/// <param name="personID"></param>

/// <returns></returns>

public int Delete(int personID)

PersonDAL3 pDAL = new PersonDAL3();

try

return pDAL.Delete(personID);

catch

throw;

finally

pDAL = null;

Till now we haev our Business Access Layer and Database Access Layer ready. Now
we have to write our Presentation Layer that will use our Business Access Layer
methods. Lets create a form that will have three textboxes for FirstName, LastName
and Age.

Presentation Layer

Create an Insert.aspx page (make is as Startup page) and copy paste following code
to bring the insert form something like displaying in the picture.
Code for Insert Record form

<asp:Label ID="lblMessage" runat="Server" ForeColor="red"


EnableViewState="False"></asp:Label>

<table style="border:2px solid #cccccc;">

<tr style="background-color:#507CD1;color:White;">

<th colspan="3">Add Records</th>

</tr>

<tr>

<td>

First Name:

</td>

<td>

<asp:TextBox ID="txtFirstName" runat="Server"></asp:TextBox>

</td>

<td>

<asp:RequiredFieldValidator ID="req1" runat="Server"


Text="*" ControlToValidate="txtFirstName"

Display="dynamic"></asp:RequiredFieldValidator>

</td>

</tr>

<tr>

<td>

Last Name:

</td>

<td>
<asp:TextBox ID="txtLastName" runat="Server"></asp:TextBox>

</td>

<td>

<asp:RequiredFieldValidator ID="req2" runat="Server"


Text="*" ControlToValidate="txtLastName"

Display="dynamic"></asp:RequiredFieldValidator>

</td>

</tr>

<tr>

<td>

Age:

</td>

<td>

<asp:TextBox ID="txtAge" runat="Server"


Columns="4"></asp:TextBox>

</td>

<td>

<asp:RequiredFieldValidator ID="req3" runat="Server"


Text="*" ControlToValidate="txtAge"

Display="dynamic"></asp:RequiredFieldValidator>

<asp:CompareValidator ID="Comp1" runat="Server" Text="Only


integer" ControlToValidate="txtAge"

Operator="DataTypeCheck"
Type="Integer"></asp:CompareValidator>

</td>

</tr>

<tr>

<td>&nbsp;</td>

<td>

<asp:Button ID="btnSubmit" runat="server" Text="Submit"


OnClick="AddRecords" />

</td>

</tr>
</table>

Now, lets write method that will fire when Submit button will be clicked on the from.
Code for AddRecords method

protected void AddRecords(object sender, EventArgs e)

//Lets validate the page first

if (!Page.IsValid)

return;

int intResult = 0;

// Page is valid, lets go ahead and insert records

// Instantiate BAL object

PersonBAL3 pBAL = new PersonBAL3();

// Instantiate the object we have to deal with

string firstName = txtFirstName.Text;

string lastName = txtLastName.Text;

int age = Int32.Parse(txtAge.Text);

try

intResult = pBAL.Insert(firstName, lastName, age);

if (intResult > 0)

lblMessage.Text = "New record inserted successfully.";

else

lblMessage.Text = "FirstName [<b>"+ txtFirstName.Text +"</b>]


alredy exists, try another name";

catch (Exception ee)


{

lblMessage.Text = ee.Message.ToString();

finally

pBAL = null;

In the above code, first I am validating the page by using Page.IsValid method just
to check if correct data has been entered. Then I have instantiated PersonBAL3 and
calling Insert method of it (pBAL.Insert) by passing firstName, lastName, age as
parameter.

Dispalying Records into GridView

Create a .aspx file called List.aspx and create a GridView something like displayed
into the picture. To list the record into GridView that will also enable us to Edit,
Delete record, copy paste following code.

Code for GridView

<asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333"


GridLines="None"

DataKeyNames="PersonID" AutoGenerateEditButton="True"
AutoGenerateColumns="False"

OnRowEditing="EditRecord" OnRowUpdating="UpdateRecord"
OnRowCancelingEdit="CancelRecord"

OnRowDeleting="DeleteRecord" PageSize="5" >

<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White"


/>

<RowStyle BackColor="#EFF3FB" />

<EditRowStyle BackColor="#2ff1BF" />

<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True"


ForeColor="#333333" />

<PagerStyle BackColor="#2461BF" ForeColor="White"


HorizontalAlign="Center" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White"
/>

<AlternatingRowStyle BackColor="White" />

<Columns>

<asp:BoundField DataField="PersonID" HeaderText="Person ID"


ReadOnly="True" SortExpression="PersonID" />

<asp:TemplateField HeaderText="First Name"


SortExpression="FirstName">

<ItemTemplate>

<%# Eval("FirstName") %>

</ItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="txtFName" runat="Server" Text='<%#


Eval("FirstName") %>'></asp:TextBox>

</EditItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText="Last Name"


SortExpression="LastName">

<ItemTemplate>

<%# Eval("LastName") %>

</ItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="txtLName" runat="Server" Text='<%#


Eval("LastName") %>'></asp:TextBox>

</EditItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText="Age" SortExpression="Age">

<ItemTemplate>

<%# Eval("Age") %>

</ItemTemplate>

<EditItemTemplate>

<asp:TextBox ID="txtAge" runat="Server" Text='<%#


Eval("Age") %>'></asp:TextBox>

</EditItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Delete?">

<ItemTemplate>

<span onclick="return confirm('Are you sure to


Delete?')">

<asp:LinkButton ID="lnBD" runat="server"


Text="Delete" CommandName="Delete"></asp:LinkButton>

</span>

</ItemTemplate>

</asp:TemplateField>

</Columns>

</asp:GridView>

Code to Load records and Displaying Records into GridView

private DataTable BindGrid()

PersonBAL3 p = new PersonBAL3();

try

DataTable dTable = p.Load();

GridView1.DataSource = dTable;

GridView1.DataBind();

catch (Exception ee)

lblMessage.Text = ee.Message.ToString();

finally

{
p = null;

return dTable;

In the above method I am instantiating PersonBAL3 class and calling Load method to
get the record into DataTable and binding it into GridView.

Code to Delete Records

protected void DeleteRecord(object sender, GridViewDeleteEventArgs e)

int personID =
Int32.Parse(GridView1.DataKeys[e.RowIndex].Value.ToString());

// instantiate BAL

PersonBAL3 pBAL = new PersonBAL3();

try

pBAL.Delete(personID);

lblMessage.Text = "Record Deleted Successfully.";

catch (Exception ee)

lblMessage.Text = ee.Message.ToString();

finally

pBAL = null;
}

GridView1.EditIndex = -1;

// Refresh the list

BindGrid();

Above method will fire when Delete link will be clicked on the GridView. In the above
code, I am instantiating PersonBAL3 and calling Delete method by passing personID
as parameter so that select reocrds will be deleted from datbase.

Code to Update records

protected void UpdateRecord(object sender, GridViewUpdateEventArgs e)

int personID =
Int32.Parse(GridView1.DataKeys[e.RowIndex].Value.ToString());

int intResult = 0;

GridViewRow row = GridView1.Rows[e.RowIndex];

TextBox tFN = (TextBox) row.FindControl("txtFName");

TextBox tLN = (TextBox)row.FindControl("txtLName");

TextBox tAge = (TextBox)row.FindControl("txtAge");

// instantiate BAL

PersonBAL3 pBAL = new PersonBAL3();

try

intResult = pBAL.Update(personID, tFN.Text, tLN.Text,


int.Parse(tAge.Text));

if (intResult > 0)

lblMessage.Text = "Record Updated Successfully.";


else

lblMessage.Text = "Record couldn't updated";

catch (Exception ee)

lblMessage.Text = ee.Message.ToString();

} finally

pBAL = null;

GridView1.EditIndex = -1;

// Refresh the list

BindGrid();

Advantages

1. Reduces tight coupling between User interface, business process and database.
2. change in database or any data access methods do not have effect on the presentation
layer.
3. It becomes easier to modify or extend your application, without breaking or recompiling the
client-side code