首页 > 代码库 > ASP.NET三层架构基础详细操作图文教程(转)

ASP.NET三层架构基础详细操作图文教程(转)

本文主要讲述Asp.net B/S结构 下基础的三层架构项目。
三层主要是指的界面UI层,逻辑层,数据层。
界面UI层:用于用户观看,体验的表示层。
逻辑层:程序运行逻辑的封装层。
数据层:程序数据相关操作的封装层。

每层当中还可以进行不同的详细划分,因为是基础教程,先领新手入门,所以不进行复杂的讲解。
本来出自http://www.cnntec.com 作者:A.Z猫 转载请注明,违者必究。
准备工具:
Microsoft Visual Studio 2008 以下简称vs08
Microsoft SQLServer 2005 以下简称 数据库
安装就不详说了。
首先,我们新建一个项目:如下图

[转载]ASP.NET三层架构基础详细操作图文教程(一)

打开VS2008后,点击创建项目,选择C#中的web项目,选择ASP.NET web应用程序,填写名称为StudyCSharp.Web
选择保存的路径,填写解决方案名称StudyCSharp,记得勾下创建解决方杂的选项。确定
建好项目后,右侧的解决方案资源管理器如下图

[转载]ASP.NET三层架构基础详细操作图文教程(一)

保存的目录中应有如下图中的文件夹和文件
[转载]ASP.NET三层架构基础详细操作图文教程(一) 

现在我们要对项目进行三层架构,刚才我们在创建项目的时候,已经创建了UI层,即web项目。
现在我们要创建BLL层和DAL层等 。如下图
[转载]ASP.NET三层架构基础详细操作图文教程(一) 

在文件中,我们选择添加,选择新建项目,弹出如下图
[转载]ASP.NET三层架构基础详细操作图文教程(一)
左侧,我们选择windows项目,右则我们选择类库。
然后在名称中输入StudyCSharp.BLL
路径地址可以不用更改。

根据以上操作,我们再创建StudyCSharp.DAL和StudyCSharp.Entity及StudyCSharp.Utility
创建完如下图:
[转载]ASP.NET三层架构基础详细操作图文教程(一) 
各项目说明:
StudyCSharp.Web项目:表示层,用于显示给用户观看和操作体验的
StudyCSharp.BLL项目:逻辑层,程序实现逻辑
StudyCSharp.DAL项目:数据层,程序数据相关操作封装
StudyCSharp.Entity项目:实体类,映射数据库表结构
StudyCSharp.Utility项目:实用应用层,封装相关应用操作

项目目录中如下图:
[转载]ASP.NET三层架构基础详细操作图文教程(一) 

到此为止,三层的框架已经搭建好了,但是还不能正常运用,我们还要进行一些配置和修改。
首选,我们修改DAL层,删除默认的Class1.cs文件,新建SQLHelper.cs类和Configuration.cs类。
以下是Coniguration.cs类内容

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Data;
  5. namespace StudyCSharp.DAL
  6. {
  7.     public partial class Configuration
  8.     {
  9.         public static string DateFormat
  10.         {
  11.             get
  12.             {
  13.                 string formatStr = System.Configuration.ConfigurationManager.AppSettings["DateFormat"];
  14.                 if (formatStr == null)
  15.                 {
  16.                     return "yyyy/MM/dd HH:mm";
  17.                 }
  18.                 return "yyyy/MM/dd HH:mm";
  19.             }
  20.         }
  21.         private static string mConnectionString = string.Empty;
  22.         public static string ConnectionString
  23.         {
  24.             get
  25.             {
  26.                 if (mConnectionString == string.Empty)
  27.                 {
  28.                     mConnectionString = System.Configuration.ConfigurationManager.AppSettings["ConnectionString"];
  29.                 }
  30.                 return mConnectionString;
  31.             }
  32.             set
  33.             {
  34.                 mConnectionString = value;
  35.             }
  36.         }
  37.         static EnumNetDbType mDbType = EnumNetDbType.Sql;
  38.         public static EnumNetDbType DbType
  39.         {
  40.             get
  41.             {
  42.                 return mDbType;
  43.             }
  44.             set
  45.             {
  46.                 mDbType = value;
  47.             }
  48.         }
  49.         //public static int GetOracleSequenceNextValue(string sequenceName)
  50.         //{
  51.         //    string sequel = "select  " + sequenceName + ".nextval from dual";
  52.         //    return (int)(OracleHelper.ExecuteScalar(ConnectionString, CommandType.Text, sequel));
  53.         //}
  54.     }
  55.     public enum EnumNetDbType
  56.     {
  57.         Sql = 0,
  58.         Oracle = 1,
  59.         OleDb = 2
  60.     }
  61.     public enum EnumPersistStatus
  62.     {
  63.         New = 0,
  64.         Update = 1,
  65.         Delete = 2
  66.     }
  67. }

添加完2个类后,我们需对DAL项目的引用文件夹点右键,选择添加引用。如图
[转载]ASP.NET三层架构基础详细操作图文教程(一) 
选择System.Configuration,确定,OK,完成以后我们再继续来配置web项目下的web.config文件,主要是连接数据库。
如下图
[转载]ASP.NET三层架构基础详细操作图文教程(一)
在appSettings节点下。原节点为<appSettings/>
我们改成如上图设置

发现很多新手不知道数据库连接字符串怎么写。简单的教下如何用vs08来自动生成这个字符串.
如下图

[转载]ASP.NET三层架构基础详细操作图文教程(一)
我们 打开web项目下的Default.aspx文件,选择拆分,然后双击左侧工具栏上的SqlDataSource控件。
会在视图和代码中生成相应的视图和代码,不用管它,我们点击控件上的配置数据源。弹出窗口如下图:

[转载]ASP.NET三层架构基础详细操作图文教程(一)
选择新建链接,如上图,在弹出窗口中,选择如上图。
然后我们根据自己的数据库来配置,选择数据库,数据库认证,输入用户名,密码,保存密码,选择数据库。点高级,出现如下图
[转载]ASP.NET三层架构基础详细操作图文教程(一)
弹出如上图对话框,就可以复制这个字符串,这个字符串就是链接字符串。

OK,现在我们来配置实体类。
实体类为数据库表的映射,即与数据库的表对应。
我们建立数据库为StudyCSharp,建立表为UserInformation
具体建表一下会儿给出代码。
我们在Entity项目上点击右键,选择添加类,然后写入如下图数据。
与数据库中表UserInformation对应。如图:

[转载]ASP.NET三层架构基础详细操作图文教程(一)
们做了这个数据库的实体映射后我们要怎么用呢?怎么才能操作这个实体像在操作数据库一样的呢?
我们马上来配置DAL项目。
对DAL项目右键,选择新建类。如下图:

[转载]ASP.NET三层架构基础详细操作图文教程(一)
因为是直接项目右键,所以不用做选择。直接输入名称即可
这里我们是操作的UserInformation所以我们类名命名为Userinformation_DAL.cs,确定
如下图:

[转载]ASP.NET三层架构基础详细操作图文教程(一)
然后在类中,我们添加如下名命空间的引用:

  1. Using System.Data;
  2. Using System.Data.SqlClient;

并将类前面加上public如下图

[转载]ASP.NET三层架构基础详细操作图文教程(一)
未完,照下图操作,继续添加引用

[转载]ASP.NET三层架构基础详细操作图文教程(一)

在弹出的对话框中,我们选择项目栏,选中刚才我们建立的数据训的映射类
如下图

[转载]ASP.NET三层架构基础详细操作图文教程(一)
需要的数据库脚本如下。
创建表和相关存储过程。这个不是我们主讲的核心,所以略过,赋上脚本。

  1. USE [StudyCSharp]
  2. GO
  3. SET ANSI_NULLS ON
  4. GO
  5. SET QUOTED_IDENTIFIER ON
  6. GO
  7. CREATE TABLE [dbo].[SC_Userinformation](
  8.     [ID] [int] IDENTITY(1,1) NOT NULL,
  9.     [UserName] [nvarchar](32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
  10.     [UserPassword] [nvarchar](128) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
  11. CONSTRAINT [PK_SC_Userinformation] PRIMARY KEY CLUSTERED
  12. (
  13.     [ID] ASC
  14. )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
  15. ) ON [PRIMARY]
  16. USE [StudyCSharp]
  17. GO
  18. SET ANSI_NULLS ON
  19. GO
  20. SET QUOTED_IDENTIFIER ON
  21. GO
  22. CREATE PROCEDURE [dbo].[SP_SelectAllFromUserinformatoin]        
  23. AS
  24. BEGIN
  25.         Select * from SC_userinformation
  26. END
  27. USE [StudyCSharp]
  28. GO
  29. SET ANSI_NULLS ON
  30. GO
  31. SET QUOTED_IDENTIFIER ON
  32. GO
  33. CREATE PROCEDURE [dbo].[SP_SelectAllFromUserinformatoinById]
  34.         @UID int        
  35. AS
  36. BEGIN
  37.         Select * from SC_userinformation where id=@UID
  38. END
  39. USE [StudyCSharp]
  40. GO
  41. SET ANSI_NULLS ON
  42. GO
  43. SET QUOTED_IDENTIFIER ON
  44. GO
  45. CREATE PROCEDURE [dbo].[SP_InsertUserinformatoin]
  46.         @ID int=null,
  47.         @UserName nvarchar(32),
  48.         @UserPassword nvarchar(128)
  49. AS
  50. BEGIN
  51.         Insert into SC_Userinformation
  52.         (
  53.                 UserName,
  54.                 UserPassword
  55.         )
  56.         values
  57.         (
  58.                 @UserName,
  59.                 @UserPassword
  60.         )
  61.         select @@identity as ‘identity‘
  62. END
  63. USE [StudyCSharp]
  64. GO
  65. SET ANSI_NULLS ON
  66. GO
  67. SET QUOTED_IDENTIFIER ON
  68. GO
  69. CREATE PROCEDURE [dbo].[SP_UpdateUserinformatoin]
  70.         @ID int,
  71.         @UserName nvarchar(32),
  72.         @UserPassword nvarchar(128)
  73. AS
  74. BEGIN
  75.         Update SC_Userinformation
  76.         SET UserName=@UserName,
  77.                 UserPassword=@UserPassword
  78.         where ID=@ID
  79. END
  80. USE [StudyCSharp]
  81. GO
  82. SET ANSI_NULLS ON
  83. GO
  84. SET QUOTED_IDENTIFIER ON
  85. GO
  86. CREATE PROCEDURE [dbo].[SP_UserLogin]
  87.         @UserName nvarchar(32),
  88.         @UserPassword nvarchar(128)
  89. AS
  90. BEGIN
  91.         select count(id)
  92.         from SC_UserInformation
  93.         where username=@UserName
  94.         and userPassword=@UserPassword
  95. END
复制代码

存储过程相关调用,详细Userinformation_DAL.cs中的说明。

附上Userinformation_DAL.cs文件内容如下

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Data;
  5. using System.Data.SqlClient;
  6. namespace StudyCSharp.DAL
  7. {
  8.     public partial class Userinformation_DAL
  9.     {
  10.         /// <summary>
  11.         /// 用户登录验证
  12.         /// </summary>
  13.         /// <param name="userName">用户名</param>
  14.         /// <param name="userPassword">密码</param>
  15.         /// <returns>布尔值True成功</returns>
  16.         public static bool UserLogin(string userName, string userPassword)
  17.         {
  18.             string sequel = "SP_UserLogin";
  19.             SqlParameter[] paras = new SqlParameter[]
  20.             {
  21.                 new SqlParameter("@UserLoginName", userName),
  22.                 new SqlParameter("@UserPassword",userPassword)
  23.             };
  24.             int result =(int)SqlHelper.ExecuteScalar(Configuration.ConnectionString, CommandType.StoredProcedure, sequel, paras);
  25.             if (result > 0)
  26.             {
  27.                 return true;
  28.             }
  29.             else
  30.             {
  31.                 return false;
  32.             }
  33.         }
  34.         /// <summary>
  35.         /// 添加新用户
  36.         /// </summary>
  37.         /// <param name="ui">用户信息实体</param>
  38.         /// <returns>用户编号</returns>
  39.         public static int CreateUserInfo(StudyCSharp.Entity.UserInformation ui)
  40.         {
  41.             string sequel = "SP_InsertUserinformatoin";
  42.             SqlParameter[] paras = (SqlParameter[])ValueParas(ui);
  43.             int result = SqlHelper.ExecuteNonQuery(Configuration.ConnectionString, CommandType.StoredProcedure, sequel, paras);
  44.             return result;
  45.         }
  46.         /// <summary>
  47.         /// 获取用户所有信息
  48.         /// </summary>
  49.         /// <returns>泛型实体</returns>
  50.         public static List<StudyCSharp.Entity.UserInformation> GetAllUserInfo()
  51.         {
  52.             string sequel = "SP_SelectAllFromUserinformatoin";            
  53.             DataTable dt = SqlHelper.ExecuteDataSet(Configuration.ConnectionString, CommandType.StoredProcedure, sequel,null).Tables[0];
  54.             return LoadListFromDataView(dt.DefaultView);
  55.         }
  56.         /// <summary>
  57.         /// 获取用户所有信息同上,不同的是不是调用的存储过程,而是直接拼写的SQL
  58.         /// </summary>
  59.         /// <returns>DataTable</returns>
  60.         public static DataTable GetAllUserInfoBySql()
  61.         {
  62.             string sequel = "Select * from SC_UserInformation";
  63.             DataTable dt = SqlHelper.ExecuteDataSet(Configuration.ConnectionString, CommandType.Text, sequel, null).Tables[0];
  64.             return dt;
  65.         }
  66.         /// <summary>
  67.         /// 获取某用户信息
  68.         /// </summary>
  69.         /// <param name="empId">用户id</param>
  70.         /// <returns>用户信息实体</returns>
  71.         public static StudyCSharp.Entity.UserInformation GetUserInfoByEmpId(string empId)
  72.         {
  73.             string sequel = "SP_SelectAllFromUserinformatoinById";
  74.             SqlParameter[] paras = new SqlParameter[] { new SqlParameter("@UID", empId) };
  75.             DataTable dt = SqlHelper.ExecuteDataSet(Configuration.ConnectionString, CommandType.StoredProcedure, sequel, paras).Tables[0];
  76.             if (dt.Rows.Count == 0)
  77.             {
  78.                 return null;
  79.             }
  80.             else
  81.             {
  82.                 DataRow row = dt.Rows[0];
  83.                 return GetEntity(row);
  84.             }
  85.         }
  86.         /// <summary>
  87.         /// 更新用户信息
  88.         /// </summary>
  89.         /// <param name="ui">用户实体</param>
  90.         /// <returns>影响行数</returns>
  91.         public static int UpdateUserInfo(StudyCSharp.Entity.UserInformation ui)
  92.         {
  93.             string sequel = "SP_UpdateUserinformatoin";
  94.             SqlParameter[] paras = (SqlParameter[])ValueParas(ui);
  95.             int result = SqlHelper.ExecuteNonQuery(Configuration.ConnectionString, CommandType.StoredProcedure, sequel, paras);
  96.             return result;  
  97.         }
  98.         /// <summary>
  99.         /// 将DataView转换为泛型实体对象
  100.         /// </summary>
  101.         /// <param name="dv">DataView</param>
  102.         /// <returns>泛型实体对象</returns>
  103.         private static List<StudyCSharp.Entity.UserInformation> LoadListFromDataView(DataView dv)
  104.         {
  105.             List<StudyCSharp.Entity.UserInformation> list = new List<StudyCSharp.Entity.UserInformation>();
  106.             for (int index = 0; index <= dv.Count - 1; index++)
  107.             {
  108.                 list.Add(GetEntity(dv[index].Row));
  109.             }
  110.             return list;
  111.         }
  112.                 /// <summary>
  113.                 /// 从DataReader中读取数据映射到实体类的属性中
  114.                 /// </summary>
  115.                 /// <remarks></remarks>
  116.                 private static StudyCSharp.Entity.UserInformation GetEntity(IDataReader dataReader)
  117.                 {
  118.                         StudyCSharp.Entity.UserInformation _obj = new StudyCSharp.Entity.UserInformation();
  119.                         if (!dataReader["ID"].Equals(DBNull.Value))
  120.                                 _obj.ID = Convert.ToInt32(dataReader["ID"]);
  121.                         if (!dataReader["UserName"].Equals(DBNull.Value))
  122.                                 _obj.UserName = Convert.ToString(dataReader["UserName"]);
  123.                         if (!dataReader["UserPassword"].Equals(DBNull.Value))
  124.                                 _obj.UserPassword = Convert.ToString(dataReader["UserPassword"]);
  125.                         return _obj;
  126.                 }
  127.                 /// <summary>
  128.                 /// 从行中读取数据映射到实体类的属性中
  129.                 /// </summary>
  130.                 /// <remarks></remarks>
  131.                 private static StudyCSharp.Entity.UserInformation GetEntity(DataRow row)
  132.                 {
  133.                         StudyCSharp.Entity.UserInformation _obj = new StudyCSharp.Entity.UserInformation();
  134.                         if (!row["ID"].Equals(DBNull.Value))
  135.                                 _obj.ID = Convert.ToInt32(row["ID"]);
  136.                         if (!row["UserName"].Equals(DBNull.Value))
  137.                                 _obj.UserName = Convert.ToString(row["UserName"]);
  138.                         if (!row["UserPassword"].Equals(DBNull.Value))
  139.                                 _obj.UserPassword = Convert.ToString(row["UserPassword"]);
  140.                         return _obj;
  141.                 }
  142.                 /// <summary>
  143.                 /// 该数据访问对象的属性值装载到数据库更新参数数组Insert用
  144.                 /// </summary>
  145.                 /// <remarks></remarks>
  146.                 private static IDbDataParameter[] ValueParas(StudyCSharp.Entity.UserInformation _obj)
  147.                 {
  148.                         SqlParameter[] paras = new SqlParameter[3];
  149.                         paras[0] = new SqlParameter("@ID", _obj.ID);
  150.                         paras[1] = new SqlParameter("@UserName", _obj.UserName);
  151.                         paras[2] = new SqlParameter("@UserPassword", _obj.UserPassword);
  152.                         paras[0].DbType = DbType.Int32;
  153.                         paras[1].DbType = DbType.String;
  154.                         paras[2].DbType = DbType.String;
  155.                         return paras;
  156.                 }
  157.         }
  158. }

下篇解析三层架构的DAL及BLL还有WEB之间的关系和调用。

之前我们说过了DAL层,现在我们来讲一下BLL层。BLL层是逻辑层,位于数据层之上。
那么我们应该不难看出,BLL层需要调用DAL层的方法。于是,我们必须在BLL层的引用目录鼠标右键,添加引用
添加上StudyCSharp.DAL和StudyCSharp.Entity以及StudyCSharp.Utility三个项目的引用。如图:



[转载]ASP.NET三层架构基础详细操作图文教程(二)

然后我们在BLL项目中添加Userinformation_BLL.cs类文件。
如图:

[转载]ASP.NET三层架构基础详细操作图文教程(二)


没错,Userinformation_BLL.cs类就是逻辑类。
我们先把DAL层的方法都COPY过来,因为他们是要是BLL层里实现的,当然我是倒着讲的,所以现在我们倒着在实现,嘿嘿。按理来说,我们应该先UI,再BLL,最后再DAL。为了方便大家深入了理解,所以我就反着来了。
COPY过来后,我们删掉方法内的内容,然后调用DAL相应的方法如下:

[转载]ASP.NET三层架构基础详细操作图文教程(二) 
这就是引用的目地。
[转载]ASP.NET三层架构基础详细操作图文教程(二) 
这是逻辑层,当然会简简单单的传入表示层的参数,获得数据层的数据返回。
因为这里举的是简单的用户信息增,删,改,查的小例子,所以逻辑不是很复。
我们中修改几个方法,第一个是CreateUserInfo另一个是UpdateUserInfo,还有一个UserLogin类
主要是将用户传入的密码参数进行加密。因为我们是使用的实体类型,所以就很好操作了。
在此之前,我们需要在StudyCSharp.Utility添加一个MD5类,即加密类。
因为在MD5类中,我们使用了FormsAuthentication类,所以我们在在Utility项目下对引用目录点右键,添加对system.web的引用。
如下:
[转载]ASP.NET三层架构基础详细操作图文教程(二) 
并在类的命名空间上引用

using System.Web.Security;

如下图

[转载]ASP.NET三层架构基础详细操作图文教程(二)
下面是我们修改Userinformation_BLL.cs中的方法,给用户的密码加密。
如图:

[转载]ASP.NET三层架构基础详细操作图文教程(二)

讲到这里,我们已经把BLL和DAL都封装好了。接下来的就只是调用。因为本文主要是讲述的ASP.NET的三层架构,所以从最底层的DAL到BLL到现在UI反着来的,如果是现实中的项目咱们就不能这么做了。得先做需求,然后做设计,然后搭建框架针对不同的模块,进行不同的封装。先UI,再BLL,最后DAL,因为总是逻辑后才会知道需要对数据怎么操作。但在这之前都是用户的体验优先,因为展示给用户使用,操作和体验的UI层可能会引导你的代码逻辑。好啦,今天我们主要是讲下在UI层下,我们怎么与BLL层通迅。
首先,我们来说说要要在界面上实现的一些效果。
第一,实现用户注册,用户需要输入用户名和密码。然后注册 。
第二,注册成功后用户可以登录系统。
第三,登录系统后用户可以查看用户列表。
OK,因为是示例,我也不多做业面,就全都在Default.aspx页面上实现了。界面结构如下图


视图如下:

那么在逻辑层我们就实现了简单的逻辑,将用户的传入的密码进行加密。无论是更新,新增,还是对比数据库查询。
到此,DAL,BLL,Utility三个层的处理就完了。剩下的就是UI表示层了。在表示层,我们就会详细的看到通过逻辑处理和数据处理后在表示层上面的调用了。
我们主要是实现对用户的注册,登录和查询。


[转载]ASP.NET三层架构基础详细操作图文教程(三) 

[转载]ASP.NET三层架构基础详细操作图文教程(三)
我们要在web项目中去调用BLL和Entity的信息我们就必须对它们添加引用。添加引用说过很多次了就不重复了。
然后我们就可以调用BLL中封装的方法。
具本Default.aspx.cs页面代码如下:

using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace StudyCSharp.Web
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
           
        }

        /// <summary>
        /// 将泛型用户信息实体类型绑定到列表上。注意,绑定泛型数据时,GridView的列不能自动生成。
        /// </summary>
        private void GridDataBandByList()
        {
            gvUserInfo.DataSource = StudyCSharp.BLL.Userinformation_BLL.GetAllUserInfo();
            gvUserInfo.DataBind();
        }

        /// <summary>
        /// 将DataTable数据集绑定到列表上。
        /// </summary>
        private void GridDataBandByDataTable()
        {
            gvUserInfo.DataSource = StudyCSharp.BLL.Userinformation_BLL.GetAllUserInfoBySql();
            gvUserInfo.DataBind();
        }

        protected void btnAddUserInfo_Click(object sender, EventArgs e)
        {
            StudyCSharp.Entity.UserInformation user = new StudyCSharp.Entity.UserInformation();
            user.ID = 0;
            user.UserName = txtUserName.Text.Trim();
            user.UserPassword = txtUserPassword.Text.Trim();
            if (StudyCSharp.BLL.Userinformation_BLL.CreateUserInfo(user) > 0)
            {
                //注册成功后我们用数据集DataTable绑定
                GridDataBandByDataTable();
            }
            else
            {
                Response.Write("注册失败");
            }
        }

        protected void btnUserLogin_Click(object sender, EventArgs e)
        {
            if (StudyCSharp.BLL.Userinformation_BLL.UserLogin(txtLoginUserName.Text.Trim(), txtLoginUserPassword.Text.Trim()))
            {
                //登录成功后我们用泛型绑定
                GridDataBandByList();
                Response.Write("登录成功!");
            }
            else
            {
                Response.Write("用户名或密码错误!");
            }
        }
    }   
}

下图为最终效果:
 
[转载]ASP.NET三层架构基础详细操作图文教程(三)