【ASP.NET開發】ASP.NET(MVC)三層架構知識的學習總結

zhiqiang21發表於2012-09-27

至從使用過一次MVC進行團隊開發後,體會到了物件導向開發軟體的便利。使用MVC的時候,各個層之間的低耦合使得他們之間的聯絡非常的第,也就降低了模組之間的依賴程度。

首先介紹一下MVC的意義,和各個層面之間的用途和功能。

1)實體層。主要用來宣告在檢視層和業務邏輯層之間傳遞資料的載體。通常代表來源與專案資料庫中一個或者多個表組成的一條有意義的記錄。

2)業務邏輯層。根據業務邏輯向檢視層提供資料,這個專案中的類有權根據業務邏輯來決定是否呼叫資料庫訪問層的方法

3)資料庫訪問層。項業務邏輯層提供訪問資料的方法。

4)檢視層。主要是以網站開發為例。用於提供顯示,新增,編輯和刪除資料。

我在VS中建立的專案的結構圖:


NetMVC就是所謂的檢視層。Entity是實體層,用來宣告開發過程中被要使用的所有變數。DAL是資料庫訪問層,主要完成所有操作對資料庫的訪問。BLL是業務邏輯層,處理檢視層傳來的業務邏輯,然後傳遞給資料庫訪問層進行處理。

本例主要演示的是登陸頁面的實現,Entity層的程式碼如下:

using System;
using System.Collections.Generic;
using System.Text;

namespace Entity
{
    public class UserInfo
    {
        private int UserId;

        /// <summary>
        /// 使用者比編號
        /// </summary>
        public int UserId1
        {
            get { return UserId; }
            set { UserId = value; }
        }
        private string username;

        /// <summary>
        /// 登入賬戶名稱
        /// </summary>
        public string Username
        {
            get { return username; }
            set { username = value; }
        }

        private string password;

        /// <summary>
        /// 登入密碼
        /// </summary>
        public string Password
        {
            get { return password; }
            set { password = value; }
        }
        private int loginCount;

        /// <summary>
        /// 登陸次數
        /// </summary>
        public int LoginCount
        {
            get { return loginCount; }
            set { loginCount = value; }
        }
        private DateTime regDate;

        /// <summary>
        /// 註冊時間
        /// </summary>
        public DateTime RegDate
        {
            get { return regDate; }
            set { regDate = value; }
        }
        private DateTime lastLoginDate;

        /// <summary>
        /// 最後登入時間
        /// </summary>
        public DateTime LastLoginDate
        {
            get { return lastLoginDate; }
            set { lastLoginDate = value; }
        }
        private bool isForbidden;
        private string passwordQuestion;

        /// <summary>
        /// 找回密碼提示問題
        /// </summary>
        public string PasswordQuestion
        {
            get { return passwordQuestion; }
            set { passwordQuestion = value; }
        }
        private string passwordAnswer;

        /// <summary>
        /// 找回密碼答案
        /// </summary>
        public string PasswordAnswer
        {
            get { return passwordAnswer; }
            set { passwordAnswer = value; }
        }


    }
}

完成對實體類的建立,接著就要完成對資料庫訪問層的建立(其中需要用到上篇問章所寫的SqlHelper資料庫訪問通用類http://blog.csdn.net/yisuowushinian/article/details/7999305),程式碼如下,

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using Entity;

namespace DAL
{
    public class UserDal
    {
        private string connectionString = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;

        /// <summary>
        /// 新增使用者
        /// </summary>
        /// <param name="info">使用者的實體類</param>
        /// <returns></returns>
        public bool AddUser(UserInfo info)
        {
            string sql = "insert into Users(Username,password) values('@Username','@password')";
            SqlParameter[] parameters = new SqlParameter[4];
            parameters[0] = new SqlParameter("@Username", SqlDbType.NVarChar, 30);
            parameters[0].Value = info.Username;

            parameters[1] = new SqlParameter("password", SqlDbType.VarChar, 50);
            parameters[1].Value = info.Password;


            return new SqlDbHelper(connectionString).ExecuteNonQuery(sql) > 0;
        }

        /// <summary>
        /// 刪除使用者
        /// </summary>
        /// <param name="UserId">使用者編號</param>
        /// <returns></returns>
        public bool DeleteUser(int UserId)
        {
            string sql = "delete from users where UserId=" + UserId;
            return new SqlDbHelper(connectionString).ExecuteNonQuery(sql) > 0;
        }

        /// <summary>
        /// 更新使用者
        /// </summary>
        /// <param name="info">使用者的實體類</param>
        /// <returns></returns>
        public bool UpDateUser(UserInfo info)
        {
            string sql = "update users set password=@password,loginCount=@loginCount where userid=@userid";
            SqlParameter[] parameters = new SqlParameter[7];
            parameters[0] = new SqlParameter("@password", SqlDbType.VarChar, 30);
            parameters[0].Value = info.Password;

            parameters[1] = new SqlParameter("@loginCount", SqlDbType.Int, 4);
            parameters[1].Value = info.LoginCount;

            return new SqlDbHelper(connectionString).ExecuteNonQuery(sql) > 0;
        }

        /// <summary>
        /// 根據使用者名稱或者使用者編號查詢使用者
        /// </summary>
        /// <param name="userId">使用者編號</param>
        /// <returns></returns>
        public DataTable GetUser(int userId)
        {
            string sql = "select * from users where userId=@UserId";
            SqlParameter[] parameters = new SqlParameter[1];
            parameters[0] = new SqlParameter("@UserId", SqlDbType.Int, 4);
            parameters[0].Value = userId;
            return new SqlDbHelper(connectionString).ExecuteDataTable(sql, CommandType.Text, parameters);
        }

        /// <summary>
        /// 根據使用者名稱查詢使用者資訊
        /// </summary>
        /// <param name="Username">使用者名稱</param>
        /// <returns></returns>
        public DataTable GetUser(string Username)
        {
            string sql = "select * from users where username=@username";
            SqlParameter[] parameters = new SqlParameter[1];
            parameters[1] = new SqlParameter("@username", SqlDbType.NVarChar, 30);
            parameters[1].Value = Username;

            return new SqlDbHelper(connectionString).ExecuteDataTable(sql, CommandType.Text, parameters);
        }

        /// <summary>
        /// 按照使用者編號升序查詢從指定位置開始的指定條數記錄
        /// </summary>
        /// <param name="startIndex">查詢的起始位置</param>
        /// <param name="size">返回的最大記錄條數</param>
        /// <returns></returns>
        public DataTable GetUserList(int startIndex, int size)
        {
            string sql = "select top " + size + " * from users where UserId not in (select top " + startIndex + " UserId from Users order by UserId asc)order by UserId asc";
            return new SqlDbHelper(connectionString).ExecuteDataTable(sql);
        }

        /// <summary>
        /// 查詢使用者總數
        /// </summary>
        /// <returns></returns>
        public int GetUserCount()
        {
            string sql = "select count(1) from Users";
            return int.Parse(new SqlDbHelper(connectionString).ExecuteScalar(sql).ToString());
        }
    }
}

然後建立業務邏輯層,程式碼如下:

using System;
using System.Collections.Generic;
using System.Text;

using DAL;
using Entity;
using System.Data;
using System.Data.SqlClient;
using System.Security.Cryptography;
using System.Security;

namespace BLL
{
    public class UserBLL
    {
        private static string MD5Hash(string password)
        {
            MD5 md5 = MD5.Create();//建立Md5演算法例項
            //將原始字串轉換成UTF-8編碼的位元組陣列
            byte[] sourceBytes = System.Text.Encoding.UTF8.GetBytes(password);
            //計算位元組陣列的雜湊值
            byte[] resultBytes = md5.ComputeHash(sourceBytes);
            StringBuilder buffer = new StringBuilder(resultBytes.Length);
            //將計算得到的雜湊值的位元組陣列中的每一個位元組轉換成十六進位制形式
            foreach (byte b in resultBytes)
            {
                buffer.Append(b.ToString("X"));

            }
            return buffer.ToString();
        }

        /// <summary>
        /// 新增使用者
        /// </summary>
        /// <param name="info">使用者的實體類</param>
        /// <returns></returns>
        public static bool AddUser(UserInfo info)
        {
            UserDal dal = new UserDal();
            DataTable data = dal.GetUser(info.Username);
            if (data.Rows.Count > 0)
            {
                return false;
            }
            else
            {
                info.Password =MD5Hash (info.Password);
                return new UserDal().AddUser(info);
            }
        }

        /// <summary>
        /// 刪除使用者
        /// </summary>
        /// <param name="userId">使用者編號</param>
        /// <returns></returns>
        public static bool DeleteUser(int userId)
        {
            return new UserDal().DeleteUser(userId);
        }

        /// <summary>
        /// 更新使用者
        /// </summary>
        /// <param name="info">使用者的實體類</param>
        /// <param name="changePassword">是否需要對使用者密碼進行加密</param>
        /// <returns></returns>
        public static bool UpdateUser(UserInfo info, bool changePassword)
        {
            //如果更改密碼就需要對新密碼進行加密
            //如果沒有更改密碼則不能對密碼重複加密,否則會對使用者造成無法登陸
            if (changePassword)
            {
                info.Password = MD5Hash(info.Password);
            }
            return new UserDal().UpDateUser(info);
        }

        /// <summary>
        /// 根據使用者編號查詢使用者
        /// </summary>
        /// <param name="UserId">使用者的編號</param>
        /// <returns></returns>
        public static DataTable GetUser(int UserId)
        {
            return new UserDal().GetUser(UserId);
        }

        /// <summary>
        /// 根據使用者名稱查詢使用者資訊
        /// </summary>
        /// <param name="userName">使用者名稱</param>
        /// <returns></returns>
        public static DataTable GetUser(string userName)
        {
            return new UserDal().GetUser(userName);
        }

        /// <summary>
        /// 按照使用者編號升序查詢從指定位置開始的指定條數的記錄
        /// </summary>
        /// <param name="startIndex">查詢的起始位置</param>
        /// <param name="size">返回的最大記錄條數</param>
        /// <returns></returns>
        public static DataTable GetUserList(int startIndex, int size)
        {
            return new UserDal().GetUserList(startIndex, size);
        }

        /// <summary>
        /// 查詢使用者總數
        /// </summary>
        /// <returns></returns>
        public static int GetUserCount()
        {
            return new UserDal().GetUserCount();
        }

        /// <summary>
        /// 根據使用者名稱或者使用者編號從資料庫查詢對應記錄的實體,如果不存在則返回null
        /// </summary>
        /// <param name="userId">使用者編號</param>
        /// <returns></returns>
        public static UserInfo GetUserEntity(int userId)
        {
            return ChangeToEntity(new UserDal().GetUser(userId));
        }

        /// <summary>
        /// 根據使用者名稱或者使用者編號從資料庫查詢對應記錄的實體,如果不存在則返回null
        /// </summary>
        /// <param name="userName">使用者名稱</param>
        /// <returns></returns>
        public static UserInfo GetUserEntity(string userName)
        {
            return ChangeToEntity(new UserDal().GetUser(userName));
        }

        /// <summary>
        /// 將包含Users表記錄的DataTables中的第一條記錄轉換成Userinfo實體
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static UserInfo ChangeToEntity(DataTable data)
        {
            UserInfo info = null;
            //如果data不為空並且包含的記錄條數大於0、
            if (data!=null&&data.Rows.Count > 0)
            {
                DataRow row = data.Rows[0];
                info = new UserInfo();

            }
            return info;
        }

        public static bool Login(string userName, string password)
        {
            bool exits = false;
            UserInfo info = GetUserEntity(userName);

            if (info != null && MD5Hash(password) == info.Password)
            {
                exits = true;
                info.LoginCount = info.LoginCount + 1;//將使用者登陸的次數加1
                info.LastLoginDate = DateTime.Now;//將使用者最後的登入時間設定為現在
                UpdateUser(info, false);//更新使用者的登陸次數和最後的登入時間
            }
            return exits;
        }
    }
}

這個就完成了對資料庫訪問層,實體層,業務邏輯層的建立工作。因為在建立過程中被,有很多的重複的工作,我為了加快速度,就省略了一些的程式碼。

在登陸頁面使用時,只需要引入業務邏輯層的方法,然後根據其中的方法,傳入相應的引數,就可以完成所有的操作。




相關文章