asp.net三层架构详解
一、數據庫
/*==============================================================*/
/*?DBMS?name:??????Microsoft?SQL?Server?2000????????????????????*/
/*==============================================================*/
?
?
if?exists?(select?1
????????????from?sysobjects
???????????where?id?=?object_id('newsContent')
????????????and???type?=?'U')
???drop?table?newsContent
go
?
?
/*==============================================================*/
/*?Table:?newsContent????????????????????????????????????????????*/
/*==============================================================*/
create?table?newsContent?(
???ID???????????int??????????????identity(1,1)???primary?key,
???Title??????????nvarchar(50)?????not?null,
???Content???????ntext????????????not?null,
???AddDate??????datetime?????????not?null,
??CategoryID????int??????????????not?null
)
go
?
?
?
二、項目文件架構
實現步驟為:4-3-6-5-2-1
| ? ID
| ? 項目
| ? 描述
| ? 用途
| ? 項目引用關系
| ? 實例所需文件
| ? 相關方法
|
| ? 1
| ? Web
| ? 表現層
| ? Web頁和控件
| ? 引用BLL
| ? WebUI.aspx WebUI.aspx.cs
| ? ? GetContent()
|
| ? 2
| ? BLL
| ? 業務邏輯層
| ? 業務邏輯組件
| ? 引用 IDAL,Model,使用DALFactory創建實例
| ? Content.cs
| ? ContentInfo GetContentInfo(int id)
|
| ? 3
| ? IDAL
| ? 數據訪問層接口定義
| ? 每個DAL實現都要實現的一組接口
| ? 引用 Model
| ? IContent.cs
| ? ContentInfo GetContentInfo(int id)
|
| ? 4
| ? Model
| ? 業務實體
| ? 傳遞各種數據的容器
| ? 無引用
| ? ContentInfo.cs
| ? ?
|
| ? 5
| ? DALFactory
| ? 數據層的抽象工廠
| ? 創建反射,用來確定加載哪一個數據庫訪問程序集的類
| ? 引用IDAL,通過讀取web.config里設置的程序集,加載類的實例,返回給BLL使用。
| ? Content.cs
| ? IDAL.Icontent create()
|
| ? 6
| ? SQLServerDAL
| ? SQLServer數據訪問層
| ? Microsoft SQL Server特定的Pet Shop DAL實現,使用了IDAL接口
| ? 引用 Model和IDAL,被DALFactory加載的程序集,實現接口里的方法。
| ? SqlHelper.cs ? ? ? Content.cs
| ? SqlDataReader ExecuteReader() PrepareCommand() ContentInfo GetContentInfo(int id)
|
| ? OracleDAL
| ? Oracle數據訪問層
| |||||
| ? 7
| ? DBUtility
| ? 數據庫訪問組件基礎類
| ? GetSqlServerConnectionString得到數據庫連接字符串,也可省去該項目,在SQLServerDAL.SqlHelper中用static readonly string SqlConnectionString代替。
| ? 無引用
| ? ?
| ? ?
|
?
實現步驟過程
1、創建Model,實現業務實體。
2、創建IDAL,實現接口。
3、創建SQLServerDAL,實現接口里的方法。
4、增加web.config里的配置信息,為SQLServerDAL的程序集。
5、創建DALFactory,返回程序集的指定類的實例。
6、創建BLL,調用DALFactory,得到程序集指定類的實例,完成數據操作方法。
7、創建WEB,調用BLL里的數據操作方法。
注意:
1、web.config里的程序集名稱必須與SQLServerDAL里的輸出程序集名稱一致。
2、DALFactory里只需要一個DataAccess類,可以完成創建所有的程序集實例。
3、項目創建后,注意修改各項目的默認命名空間和程序集名稱。
4、注意修改解決方案里的項目依賴。
5、注意在解決方案里增加各項目引用。
?
三、各層間的訪問過程
1、傳入值,將值進行類型轉換(為整型)。
2、創建BLL層的content.cs對象c,通過對象c訪問BLL層的方法GetContentInfo(ID)調用BLL層。
3、BLL層方法GetContentInfo(ID)中取得數據訪問層SQLServerDAL的實例,實例化IDAL層的接口對象dal,這個對象是由工廠層DALFactory創建的,然后返回IDAL層傳入值所查找的內容的方法dal.GetContentInfo(id)。
4、數據工廠通過web.config配置文件中給定的webdal字串訪問SQLServerDAL層,返回一個完整的調用SQLServerDAL層的路徑給 BLL層。
5、到此要調用SQLServerDAL層,SQLServerDAL層完成賦值Model層的對象值為空,給定一個參數,調用SQLServerDAL層的SqlHelper的ExecuteReader方法,讀出每個字段的數據賦值給以定義為空的Model層的對象。
6、SqlHelper執行sql命令,返回一個指定連接的數據庫記錄集,在這里需要引用參數類型,提供為打開連接命令執行做好準備PrepareCommand。
7、返回Model層把查詢得到的一行記錄值賦值給SQLServerDAL層的引入的Model層的對象ci,然后把這個對象返回給BLL。
8、回到Web層的BLL層的方法調用,把得到的對象值賦值給Lable標簽,在前臺顯示給界面
?
四、項目中的文件清單
?
1、DBUtility項目
(1)connectionInfo.cs
using?System;
using?System.Configuration;
?
namespace?Utility
{
???????///?<summary>
???????///?ConnectionInfo?的摘要說明。
???????///?</summary>
???????public?class?ConnectionInfo
???????{
??????????????public?static?string?GetSqlServerConnectionString()
??????????????{
?????????????????????return?ConfigurationSettings.AppSettings["SQLConnString"];
??????????????}
???????}
}
?
2、SQLServerDAL項目
(1)SqlHelper.cs抽象類
using?System;
using?System.Data;
using?System.Data.SqlClient;
using?DBUtility;
?
namespace?SQLServerDAL
{
???????///?<summary>
???????///?SqlHelper?的摘要說明。
???????///?</summary>
???????public?abstract?class?SqlHelper
???????{
??????????????public?static?readonly?string?CONN_STR?=?ConnectionInfo.GetSqlServerConnectionString();
?
??????????????///?<summary>
??????????????///?用提供的函數,執行SQL命令,返回一個從指定連接的數據庫記錄集
??????????????///?</summary>
??????????????///?<remarks>
??????????????///?例如:
??????????????///?SqlDataReader?r?=?ExecuteReader(connString,?CommandType.StoredProcedure,?"PublishOrders",?new?SqlParameter("@prodid",?24));
??????????????///?</remarks>
??????????????///?<param?name="connectionString">SqlConnection有效的SQL連接字符串</param>
??????????????///?<param?name="commandType">CommandType:CommandType.Text、CommandType.StoredProcedure</param>
??????????????///?<param?name="commandText">SQL語句或存儲過程</param>
??????????????///?<param?name="commandParameters">SqlParameter[]參數數組</param>
??????????????///?<returns>SqlDataReader:執行結果的記錄集</returns>
??????????????public?static?SqlDataReader?ExecuteReader(string?connString,?CommandType?cmdType,?string?cmdText,?params?SqlParameter[]?cmdParms)
??????????????{
?????????????????????SqlCommand?cmd?=?new?SqlCommand();
?????????????????????SqlConnection?conn?=?new?SqlConnection(connString);
?
?????????????????????//?我們在這里用?try/catch?是因為如果這個方法拋出異常,我們目的是關閉數據庫連接,再拋出異常,
?????????????????????//?因為這時不會有DataReader存在,此后commandBehaviour.CloseConnection將不會工作。
?????????????????????try
?????????????????????{
????????????????????????????PrepareCommand(cmd,?conn,?null,?cmdType,?cmdText,?cmdParms);
????????????????????????????SqlDataReader?rdr?=?cmd.ExecuteReader(CommandBehavior.CloseConnection);
????????????????????????????cmd.Parameters.Clear();
????????????????????????????return?rdr;
?????????????????????}
?????????????????????catch
?????????????????????{
????????????????????????????conn.Close();
????????????????????????????throw;
?????????????????????}
??????????????}
?
?
??????????????///?<summary>
??????????????///?為執行命令做好準備:打開數據庫連接,命令語句,設置命令類型(SQL語句或存儲過程),函數語取。
??????????????///?</summary>
??????????????///?<param?name="cmd">SqlCommand?組件</param>
??????????????///?<param?name="conn">SqlConnection?組件</param>
??????????????///?<param?name="trans">SqlTransaction?組件,可以為null</param>
??????????????///?<param?name="cmdType">語句類型:CommandType.Text、CommandType.StoredProcedure</param>
??????????????///?<param?name="cmdText">SQL語句,可以為存儲過程</param>
??????????????///?<param?name="cmdParms">SQL參數數組</param>
??????????????private?static?void?PrepareCommand(SqlCommand?cmd,?SqlConnection?conn,?SqlTransaction?trans,?CommandType?cmdType,?string?cmdText,?SqlParameter[]?cmdParms)
??????????????{
?
?????????????????????if?(conn.State?!=?ConnectionState.Open)
????????????????????????????conn.Open();
?
?????????????????????cmd.Connection?=?conn;
?????????????????????cmd.CommandText?=?cmdText;
?
?????????????????????if?(trans?!=?null)
????????????????????????????cmd.Transaction?=?trans;
?
?????????????????????cmd.CommandType?=?cmdType;
?
?????????????????????if?(cmdParms?!=?null)
?????????????????????{
????????????????????????????foreach?(SqlParameter?parm?in?cmdParms)
???????????????????????????????????cmd.Parameters.Add(parm);
?????????????????????}
??????????????}
???????}
}
?
(2)Content.cs類
using?System;
using?System.Data;
using?System.Data.SqlClient;
using?Model;
using?IDAL;
?
namespace?SQLServerDAL
{
???????///?<summary>
???????///?Content?的摘要說明。
???????///?</summary>
???????public?class?Content:IContent?
???????{
?
??????????????private?const?string?PARM_ID?=?"@ID";
??????????????private?const?string?SQL_SELECT_CONTENT?=?"Select?ID,?Title,?Content,?AddDate,?CategoryID?From?newsContent?Where?ID?=?@ID";
?
?
??????????????public?ContentInfo?GetContentInfo(int?id)
??????????????{
?????????????????????//創意文章內容類
?????????????????????ContentInfo?ci?=?null;
?
?????????????????????//創建一個參數
?????????????????????SqlParameter?parm?=?new?SqlParameter(PARM_ID,?SqlDbType.BigInt,?8);
?????????????????????//賦上ID值
?????????????????????parm.Value?=?id;
?
?????????????????????using(SqlDataReader?sdr?=?SqlHelper.ExecuteReader(SqlHelper.CONN_STR,?CommandType.Text,?SQL_SELECT_CONTENT,?parm))
?????????????????????{
????????????????????????????if(sdr.Read())
????????????????????????????{?
???????????????????????????????????ci?=?new?ContentInfo(sdr.GetInt32(0),sdr.GetString(1),?sdr.GetString(2),
??????????????????????????????????????????sdr.GetDateTime(3),?sdr.GetInt32(4),?sdr.GetInt32(5),?sdr.GetString(6));
????????????????????????????}
?????????????????????}
?????????????????????return?ci;
??????????????}
???????}
}
?
?
?
3、Model項目
(1)contentInfo.cs
using?System;
?
namespace?Model
{
???????///?<summary>
???????///?Class1?的摘要說明。
???????///?</summary>
???????public?class?ContentInfo
???????{
??????????????private?int?_ID;
??????????????private?string?_Content;
??????????????private?string?_Title;
??????????????private?string?_From;
??????????????private?DateTime?_AddDate;
??????????????private?int?_clsID;
??????????????private?int?_tmpID;
?
??????????????///?<summary>
??????????????///?文章內容構造函數
??????????????///?</summary>
??????????????///?<param?name="id">文章流水號ID</param>
??????????????///?<param?name="content">文章內容</param>
??????????????///?<param?name="title">文章標題</param>
??????????????///?<param?name="from">文章來源</param>
??????????????///?<param?name="clsid">文章的分類屬性ID</param>
??????????????///?<param?name="tmpid">文章的模板屬性ID</param>
??????????????public?ContentInfo(int?id,string?title,string?content,string?from,DateTime?addDate,int?clsid,int?tmpid?)
??????????????{
?????????????????????this._ID?=?id;
?????????????????????this._Content?=?content;
?????????????????????this._Title?=?title;
?????????????????????this._From?=?from;
?????????????????????this._AddDate?=?addDate;
?????????????????????this._clsID?=?clsid;
?????????????????????this._tmpID?=?tmpid;
??????????????}
?
?
??????????????//屬性
??????????????public?int?ID
??????????????{
?????????????????????get???{?return?_ID;?}
??????????????}
??????????????public?string?Content
??????????????{
?????????????????????get???{?return?_Content;?}
??????????????}
??????????????public?string?Title
??????????????{
?????????????????????get???{?return?_Title;?}
??????????????}
??????????????public?string?From
??????????????{
?????????????????????get???{?return?_From;?}
??????????????}
??????????????public?DateTime?AddDate
??????????????{
?????????????????????get???{?return?_AddDate;?}
??????????????}
??????????????public?int?ClsID
??????????????{
?????????????????????get???{?return?_clsID;?}
??????????????}
??????????????public?int?TmpID
??????????????{
?????????????????????get???{?return?_tmpID;?}
??????????????}
?
?
?
???????}
}
?
4、IDAL項目
(1)Icontent.cs
using?System;
using?Model;
?
namespace?IDAL
{
???????///?<summary>
???????///?文章內容操作接口
???????///?</summary>
???????public?interface?IContent
???????{
??????????????///?<summary>
??????????????///?取得文章的內容。
??????????????///?</summary>
??????????????///?<param?name="id">文章的ID</param>
??????????????///?<returns></returns>
??????????????ContentInfo?GetContentInfo(int?id);
???????}
}
?
?
5、DALFactory項目
(1)Content.cs
using?System;
using?System.Reflection;
using?System.Configuration;
using?IDAL;
?
namespace?DALFactory
{
???????///?<summary>
???????///?工產模式實現文章接口。
???????///?</summary>
???????public?class?Content
???????{
??????????????public?static?IDAL.IContent?Create()
??????????????{
?????????????????????//?這里可以查看?DAL?接口類。
?????????????????????string?path?=?System.Configuration.ConfigurationSettings.AppSettings["WebDAL"].ToString();
?????????????????????string?className?=?path+".Content";
????????????????????
?????????????????????//?用配置文件指定的類組合
?????????????????????return?(IDAL.IContent)Assembly.Load(path).CreateInstance(className);
??????????????}
???????}
}
?
?
6、BLL項目
(1)Content.cs
using?System;
?
using?Model;
using?IDAL;
?
namespace?BLL
{
???????///?<summary>
???????///?Content?的摘要說明。
???????///?</summary>
???????public?class?Content
???????{
?
??????????????public?ContentInfo?GetContentInfo(int?id)
??????????????{
?
?????????????????????//?取得從數據訪問層取得一個文章內容實例
?????????????????????IContent?dal?=?DALFactory.Content.Create();
?
?????????????????????//?用DAL查找文章內容
?????????????????????return?dal.GetContentInfo(id);
??????????????}
???????}
}
?
?
?
7、Web項目
1、Web.config:
?
<appSettings>??<add?key="SQLConnString"?value="Data?Source=localhost;Persist?Security?info=True;Initial?Catalog=newsDB;User?ID=sa;Password=?"?/>
????<add?key="WebDAL"?value="SQLServerDAL"?/>???
?</appSettings>
?
2、WebUI.aspx
<%@?Page?language="c#"?Codebehind="WebUI.aspx.cs"?AutoEventWireup="false"?Inherits="Web.WebUI"?%>
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Transitional//EN"?>
<HTML>
???????<HEAD>
??????????????<title>WebUI</title>
??????????????<meta?name="GENERATOR"?Content="Microsoft?Visual?Studio?.NET?7.1">
??????????????<meta?name="CODE_LANGUAGE"?Content="C#">
??????????????<meta?name="vs_defaultClientScript"?content="JavaScript">
??????????????<meta?name="vs_targetSchema"?content="http://schemas.microsoft.com/intellisense/ie5">
???????</HEAD>
???????<body?MS_POSITIONING="GridLayout">
??????????????<form?id="Form1"?method="post"?runat="server">
?????????????????????<FONT">宋體"></FONT>
?????????????????????<table?width="600"?border="1">
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px"> </td>
???????????????????????????????????<td>
??????????????????????????????????????????<asp:Label?id="lblTitle"?runat="server"></asp:Label></td>
????????????????????????????</tr>
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px;?HEIGHT:?22px"> </td>
???????????????????????????????????<td?style="HEIGHT:?22px">
??????????????????????????????????????????<asp:Label?id="lblDataTime"?runat="server"></asp:Label></td>
????????????????????????????</tr>
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px"> </td>
???????????????????????????????????<td>
??????????????????????????????????????????<asp:Label?id="lblContent"?runat="server"></asp:Label></td>
????????????????????????????</tr>
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px"> </td>
???????????????????????????????????<td> </td>
????????????????????????????</tr>
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px;?HEIGHT:?23px"> </td>
???????????????????????????????????<td?style="HEIGHT:?23px"> </td>
????????????????????????????</tr>
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px"> </td>
???????????????????????????????????<td> </td>
????????????????????????????</tr>
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px"> </td>
???????????????????????????????????<td> </td>
????????????????????????????</tr>
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px"> </td>
???????????????????????????????????<td> </td>
????????????????????????????</tr>
????????????????????????????<tr>
???????????????????????????????????<td?style="WIDTH:?173px"> </td>
???????????????????????????????????<td>
??????????????????????????????????????????<asp:Label?id="lblMsg"?runat="server">Label</asp:Label></td>
????????????????????????????</tr>
?????????????????????</table>
??????????????</form>
???????</body>
</HTML>
?
?
?
?
?
3、WebUI.aspx.cs后臺調用顯示:
using?System;
using?System.Collections;
using?System.ComponentModel;
using?System.Data;
using?System.Drawing;
using?System.Web;
using?System.Web.SessionState;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.HtmlControls;
?
using?BLL;
using?Model;
?
namespace?myWeb
{
???????///?<summary>
???????///?WebForm1?的摘要說明。
???????///?</summary>
???????public?class?WebUI?:?System.Web.UI.Page
???????{
??????????????protected?System.Web.UI.WebControls.Label?lblTitle;
??????????????protected?System.Web.UI.WebControls.Label?lblDataTime;
??????????????protected?System.Web.UI.WebControls.Label?lblContent;
??????????????protected?System.Web.UI.WebControls.Label?lblMsg;
?
??????????????private?ContentInfo?ci?;
?
?
??????????????private?void?Page_Load(object?sender,?System.EventArgs?e)
??????????????{
?????????????????????if(!Page.IsPostBack)
?????????????????????{
????????????????????????????GetContent("1");
?????????????????????}
??????????????}
?
??????????????private?void?GetContent(string?id)
??????????????{
?????????????????????int?ID?=?WebComponents.CleanString.GetInt(id);
?????????????
?????????????????????Content?c?=?new?Content();
?????????????????????ci?=?c.GetContentInfo(ID);
?????????????????????if(ci!=null)
?????????????????????{
????????????????????????????this.lblTitle.Text?=?ci.Title;
????????????????????????????this.lblDataTime.Text?=?ci.AddDate.ToString("yyyy-MM-dd");
????????????????????????????this.lblContent.Text?=?ci.Content;
?????????????????????}
?????????????????????else
?????????????????????{
????????????????????????????this.lblMsg.Text?=?"沒有找到這篇文章";
?????????????????????}
??????????????}
?
??????????????#region?Web?窗體設計器生成的代碼
??????????????override?protected?void?OnInit(EventArgs?e)
??????????????{
?????????????????????//
?????????????????????//?CODEGEN:?該調用是?ASP.NET?Web?窗體設計器所必需的。
?????????????????????//
?????????????????????InitializeComponent();
?????????????????????base.OnInit(e);
??????????????}
?????????????
??????????????///?<summary>
??????????????///?設計器支持所需的方法?-?不要使用代碼編輯器修改
??????????????///?此方法的內容。
??????????????///?</summary>
??????????????private?void?InitializeComponent()
??????????????{???
?????????????????????this.Load?+=?new?System.EventHandler(this.Page_Load);
?
??????????????}
??????????????#endregion
???????}
}
?
?
4、WebComponents項目
(1)CleanString.cs
using?System;
using?System.Text;
?
namespace?myWeb.WebComponents
{
???????///?<summary>
???????///?CleanString?的摘要說明。
???????///?</summary>
???????public?class?CleanString
???????{
?
??????????????public?static?int?GetInt(string?inputString)
??????????????{
?????????????????????try
?????????????????????{
????????????????????????????return?Convert.ToInt32(inputString);
?????????????????????}
?????????????????????catch
?????????????????????{
????????????????????????????return?0;
?????????????????????}
?
??????????????}
?
?
??????????????public?static?string?InputText(string?inputString,?int?maxLength)
??????????????{
?????????????????????StringBuilder?retVal?=?new?StringBuilder();
?
?????????????????????//?check?incoming?parameters?for?null?or?blank?string
?????????????????????if?((inputString?!=?null)?&&?(inputString?!=?String.Empty))
?????????????????????{
????????????????????????????inputString?=?inputString.Trim();
?
????????????????????????????//chop?the?string?incase?the?client-side?max?length
????????????????????????????//fields?are?bypassed?to?prevent?buffer?over-runs
????????????????????????????if?(inputString.Length?>?maxLength)
???????????????????????????????????inputString?=?inputString.Substring(0,?maxLength);
?
????????????????????????????//convert?some?harmful?symbols?incase?the?regular
????????????????????????????//expression?validators?are?changed
????????????????????????????for?(int?i?=?0;?i?<?inputString.Length;?i++)
????????????????????????????{
???????????????????????????????????switch?(inputString[i])
???????????????????????????????????{
??????????????????????????????????????????case?'"':
?????????????????????????????????????????????????retVal.Append(""");
?????????????????????????????????????????????????break;
??????????????????????????????????????????case?'<':
?????????????????????????????????????????????????retVal.Append("<");
?????????????????????????????????????????????????break;
??????????????????????????????????????????case?'>':
?????????????????????????????????????????????????retVal.Append(">");
?????????????????????????????????????????????????break;
??????????????????????????????????????????default:
?????????????????????????????????????????????????retVal.Append(inputString[i]);
?????????????????????????????????????????????????break;
???????????????????????????????????}
????????????????????????????}
?
????????????????????????????//?Replace?single?quotes?with?white?space
????????????????????????????retVal.Replace("'",?"?");
?????????????????????}
?
?????????????????????return?retVal.ToString();
????????????????????
??????????????}
???????????????
???????}
}
總結
以上是生活随笔為你收集整理的asp.net三层架构详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三层架构实战篇—系统登录实例
- 下一篇: .NET完全手动搭建三层B/S架构