Professional Documents
Culture Documents
based. In this article I am going to show how to design a web application based on 3-tier architecture. Download
Download source code for 3-Tier Architecture in ASP.NET with C#
Updated
on
July
01
2008:
Source
Code
attached
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
For the ease of App_Code folder. for BAL, DAL (as your
3-Tier
Architecture
understanding, I have created BAL, DAL into the In real scenario, you should create separate projects Class Library) and UI (as Web project) and reference 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)
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.
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); }
/// <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
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" EnableViewState="False"></asp:Label> runat="Server" ForeColor="red"
<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 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 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 Columns="4"></asp:TextBox> </td> <td> ID="txtAge" runat="Server" ID="txtLastName" ID="txtFirstName"
<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> </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";
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" ForeColor="#333333" GridLines="None" runat="server" CellPadding="4"
AutoGenerateEditButton="True" OnRowUpdating="UpdateRecord"
OnRowDeleting="DeleteRecord" PageSize="5" > <FooterStyle ForeColor="White" /> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2ff1BF" /> <SelectedRowStyle ForeColor="#333333" /> <PagerStyle HorizontalAlign="Center" /> <HeaderStyle ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> <Columns> ReadOnly="True" <asp:BoundField DataField="PersonID" HeaderText="Person ID" SortExpression="PersonID" /> <asp:TemplateField SortExpression="FirstName"> <ItemTemplate> <%# Eval("FirstName") %> </ItemTemplate> <EditItemTemplate> <asp:TextBox ID="txtFName" runat="Server" Text='<%# Eval("FirstName") %>'></asp:TextBox> </EditItemTemplate> </asp:TemplateField> <asp:TemplateField SortExpression="LastName"> <ItemTemplate> <%# Eval("LastName") %> </ItemTemplate> <EditItemTemplate> <asp:TextBox ID="txtLName" runat="Server" Text='<%# Eval("LastName") %>'></asp:TextBox> </EditItemTemplate> HeaderText="Last Name" HeaderText="First Name" BackColor="#D1DDF1" BackColor="#2461BF" BackColor="#507CD1" Font-Bold="True" ForeColor="White" Font-Bold="True" BackColor="#507CD1" Font-Bold="True"
</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>
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
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");
if (intResult > 0) lblMessage.Text = "Record Updated Successfully."; else lblMessage.Text = "Record couldn't updated"; } catch (Exception ee) { lblMessage.Text = ee.Message.ToString(); } { pBAL = null; } finally
Above method will fire when Update link will be clicked for a particular row of the GridView in edit mode. In the above method, I am instantiating PersonBAL3 and calling the Update method by p[assing required parameters. Now we have all set to go, now just run your project and try inserting records. You can also navigate to another page your created (list.aspx) and try updating, deleting records.
Conclusion
By using 3-Tier architecture in your project you can achive
1. Seperation - the functionality is seperated from the data access and presentation so that it is more maintainable 2. Independence - layers are established so that if one is modified (to some extent) it will not affect other layers. 3. Reusability - As the layers are seperated, it can exist as a module that can be reused by other application by referencing it. Hope this article helped you understanding 3-Tier architecture and desiging it. Thanks and Happy Coding !!!