zoukankan      html  css  js  c++  java
  • 用用户登录简单理解三层思想

    项目文件列表:

    GetUserLoginState.sc

        public class GetUserLoginState
        {
            /// <summary>
            /// 检测用户登录状态
            /// </summary>
            public GetUserLoginState()
            {
    
            }
            //推荐在此定义类型变量,而不是在方法中new一个新的对象
            private TLoginModel model;
    
    
            public UserLoginStateEnum LoginState(string userName, string password, out int ID)
            {
                TLoginDataManager manager = new TLoginDataManager();
                ID = -1;//这里是的编写思想一个亮点
                model = manager.GetUserLoginInfo(userName);
                if (model != null)
                {
                    if (model.LockTime == null || DateTime.Compare((DateTime)model.LockTime, DateTime.Now) < 0)
                    {
                        if (model.ErrorTimes == null || model.ErrorTimes < 4)//帐户锁定情况判断
                        {
                            MD5Encrypt md5 = new MD5Encrypt();
                            if (model.MD5Password == md5.Encryption(password))
                            {
                                ID = model.ID;
                                return UserLoginStateEnum.LoginSucceed;
                            }
                            else
                            {
                                manager.RaiseErrorTimes(model.ID);
                                return UserLoginStateEnum.PasswordError;
                            }
                        }
                    }
                    //这里你有疑问吗?
                    manager.LockUser(model.ID);
                    return UserLoginStateEnum.LoginFailed;
                }
                else
                {
                    return UserLoginStateEnum.NoUserName;
                }
            }
    
            public int ChangePassword(string pwd, int id)
            {
                TLoginDataManager manager = new TLoginDataManager();
                MD5Encrypt md5 = new MD5Encrypt();
                return manager.PasswordChange(md5.Encryption(pwd), id);
            }
    
            public bool VerifyPassword(string pwd, int id)
            {
                TLoginDataManager manager = new TLoginDataManager();
                MD5Encrypt md5 = new MD5Encrypt();
                return manager.VerifyPassword(md5.Encryption(pwd), id);
            }
        }
    View Code

    MD5Encrypt.cs

        public  class MD5Encrypt
        {
            /// <summary>
            /// 计算字符串 str 的HashValue
            /// </summary>
            /// <param name="str">字符串</param>
            /// <returns>返回 str 的32位HashValue</returns>
            public  string Encryption(string str)
            {
                byte[] strByte = Encoding.UTF8.GetBytes(str);
                MD5 md5 = MD5.Create();
                strByte = md5.ComputeHash(strByte);
                md5.Clear();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < strByte.Length; i++)
                {
                    sb.Append(strByte[i].ToString("x2"));
                }
                return sb.ToString();
            }
        }
    View Code

    UserLoginStateEnum.cs

        /// <summary>
        /// 表示用户登录状态
        /// </summary>
        public enum UserLoginStateEnum
        {
            NoUserName,
            PasswordError,
            LoginFailed,
            LoginSucceed
        }
    View Code

    SqlHelper.cs

        public class SqlHelper
        {
            /// <summary>
            /// 数据查询帮助类
            /// </summary>
            public SqlHelper()
            {
    
            }
    
            private string constr = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
    
            /// <summary>
            /// 对连接执行 Transact-SQL 语句并返回受影响的行数。
            /// </summary>
            /// <param name="sql">Transact-SQL 更新语句</param>
            /// <param name="param">参数</param>
            /// <returns>受影响的行数。</returns>
            public int ExecuteNonQuery(string sql, params SqlParameter[] param)
            {
                using (SqlConnection con = new SqlConnection(constr))
                {
                    using (SqlCommand cmd = new SqlCommand(sql, con))
                    {
                        if (param != null)
                        {
                            cmd.Parameters.AddRange(param);
                        }
                        con.Open();
                        return cmd.ExecuteNonQuery();
                    }
                }
            }
            /// <summary>
            /// 将 System.Data.SqlClient.SqlCommand.CommandText 发送到 System.Data.SqlClient.SqlCommand.Connection,并使用
            ///    System.Data.CommandBehavior 值之一生成一个 System.Data.SqlClient.SqlDataReader。
            /// </summary>
            /// <param name="sql">Transact-SQL 查询语句</param>
            /// <param name="param">参数</param>
            /// <returns>System.Data.SqlClient.SqlDataReader 对象。</returns>
            public SqlDataReader ExecuteReader(string sql, params SqlParameter[] param)
            {
                SqlConnection con = new SqlConnection(constr);
                try
                {
                    using (SqlCommand cmd = new SqlCommand(sql, con))
                    {
                        if (param != null)
                        {
                            cmd.Parameters.AddRange(param);
                        }
                        con.Open();
                        return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
                    }
                }
                catch (Exception)//模拟using(SqlConnection con = new SqlConnection(constr))
                {
                    con.Close();
                    con.Dispose();
                    throw;
                }
            }
            /// <summary>
            /// 执行查询,并返回查询所返回的结果集中第一行的第一列。 忽略其他列或行。
            /// </summary>
            /// <param name="sql">Transact-SQL 查询语句</param>
            /// <param name="param">参数</param>
            /// <returns>结果集中第一行的第一列;如果结果集为空,则为空引用(在 Visual Basic 中为 Nothing)。 返回的最大字符数为 2033 个字符。</returns>
            public object ExecuteScalar(string sql, params SqlParameter[] param)
            {
                using (SqlConnection con = new SqlConnection(constr))
                {
                    using (SqlCommand cmd = new SqlCommand(sql, con))
                    {
                        if (param != null)
                        {
                            cmd.Parameters.AddRange(param);
                        }
                        con.Open();
                        return cmd.ExecuteScalar();
                    }
                }
            }
            /// <summary>
            /// 执行查询,并返回查询所返回的结果集
            /// </summary>
            /// <param name="sql">Transact-SQL 查询语句</param>
            /// <param name="param">参数</param>
            /// <returns>System.Data.DataTable 对象</returns>
            public DataTable ExecuteDataTable(string sql, params SqlParameter[] param)
            {
                DataTable dt = new DataTable();
                using (SqlDataAdapter adapter = new SqlDataAdapter(sql, constr))
                {
                    if (param != null)
                    {
                        adapter.SelectCommand.Parameters.AddRange(param);
                    }
                    adapter.Fill(dt);
                }
                return dt;
            }
        }
    View Code

    TLoginDataManager.cs

        public class TLoginDataManager
        {
            /// <summary>
            /// 对Login表的数据管理
            /// </summary>
            public TLoginDataManager()
            {
    
            }
    
    
            public TLoginModel GetUserLoginInfo(string userName)
            {
                SqlHelper sqlhelper = new SqlHelper();
                string sql = "select * from MD5Login where name=@userName";
                using (SqlDataReader reader = sqlhelper.ExecuteReader(sql, new SqlParameter("@userName", userName)))
                {
                    if (reader.HasRows)
                    {
                        try
                        {
                            TLoginModel userModel = new TLoginModel();
                            while (reader.Read())
                            {
                                userModel.ID = int.Parse(reader[0].ToString());
                                userModel.Name = reader[1].ToString();
                                userModel.MD5Password = reader[2].ToString();
                                //(int)值类型 null 是不可能的:所以要做强制类型转换
                                userModel.ErrorTimes = reader.IsDBNull(3) ? null : (int?)int.Parse(reader[3].ToString());
                                userModel.LockTime = reader.IsDBNull(4) ? null : (DateTime?)DateTime.Parse(reader[4].ToString());
                                userModel.Place = reader[5].ToString();
                            }
                            //读一行可以这样写:读多行时就用List<T>集合。
                            return userModel;
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                }
                //这样做于利于弊,自己权衡吧。
                return null;
            }
    
            internal void LockUser(int p)
            {
                SqlHelper sqlhelper = new SqlHelper();
                string sql = "update MD5Login set locktime=dateadd(minute,10,getdate()),errortimes=0 where id=@id";
                sqlhelper.ExecuteNonQuery(sql, new SqlParameter("@id", p));
            }
    
            internal void RaiseErrorTimes(int p)
            {
                SqlHelper sqlhelper = new SqlHelper();
                string sql = "update MD5Login set errortimes=errortimes+1 where id=@id";
                sqlhelper.ExecuteNonQuery(sql, new SqlParameter("@id", p));
            }
    
            public int PasswordChange(string pwd, int id)
            {
                SqlHelper sqlhelper = new SqlHelper();
                string sql = "update MD5Login set MD5pwd=@pwd where id=@id";
                return sqlhelper.ExecuteNonQuery(sql, new SqlParameter("@pwd", pwd), new SqlParameter("@id", id));
            }
    
    
            internal bool VerifyPassword(string p, int id)
            {
                SqlHelper sqlhelper = new SqlHelper();
                string sql = "select * from MD5Login where id=@id and MD5pwd=@pwd";
                return sqlhelper.ExecuteReader(sql, new SqlParameter("@id", id), new SqlParameter("@pwd", p)).HasRows;
            }
        }
    View Code

    TLoginModel.cs

     public class TLoginModel
        {
            /// <summary>
            /// Login表数据模板类
            /// </summary>
            public TLoginModel()
            {
    
            }
            /// <summary>
            /// 用户id
            /// </summary>
            public int ID { get; set; }
            /// <summary>
            /// 用户名称
            /// </summary>
            public string Name { get; set; }
    
            //用不用储存密码?
            /// <summary>
            /// 用户密码的MD5值
            /// </summary>
            public string MD5Password { get; set; }
    
            /// <summary>
            /// 登录错误次数
            /// int? 表示int的可空类型(Nullable)
            /// </summary>
            public int? ErrorTimes { get; set; }
    
            /// <summary>
            /// 帐户锁定时间
            /// DateTime? 表示DateTime的可空类型(Nullable)
            /// </summary>
            public DateTime? LockTime { get; set; }
            /// <summary>
            /// 登录地点
            /// </summary>
            public string Place { get; set; }
            /// string? :错误的!!值类型 are nullable not
        }
    View Code

    UserCurrentID.cs

        public static class UserCurrentID
        {
            public static int ID { get; set; }
        }

    frmLogin类

        public partial class frmLogin : Form
        {
            public frmLogin()
            {
                InitializeComponent();
            }
    
            private UserLoginStateEnum state;
    
            private void btnLogin_Click(object sender, EventArgs e)
            {
                GetUserLoginState login = new GetUserLoginState();
                string name = txtUserName.Text.Trim();
                string password = txtPassword.Text.Trim();
                //在这里有UI的BLL,当然也可以写在BLL中
                //判断输入框不能为空的情况。
                //属性、索引器或动态成员访问不得作为 out 或 ref 参数传递    
                //state = login.LoginState(name, password, out  UserCurrentID.ID);
                int ID;
                state = login.LoginState(name, password, out ID);
                if (state == UserLoginStateEnum.LoginSucceed)
                {
                    UserCurrentID.ID = ID;
                    MessageBox.Show("登录成功");
                    this.btnPasswordChange.Enabled = true;
                }
                else if (state == UserLoginStateEnum.NoUserName)
                {
                    MessageBox.Show("用户不存在");
                }
                else if (state == UserLoginStateEnum.PasswordError)
                {
                    MessageBox.Show("密码错误");
                }
                else if (state == UserLoginStateEnum.LoginFailed)
                {
                    MessageBox.Show("错误次数过多,锁定10分钟,稍后再试。");
                }
            }
    
            private void btnPasswordChange_Click(object sender, EventArgs e)
            {
                PasswordChange changePwd = new PasswordChange();
    
                changePwd.Show();
            }
        }
    View Code

    PasswordChange类

        public partial class PasswordChange : Form
        {
            public PasswordChange()
            {
                InitializeComponent();
            }
    
            private void btnCancel_Click(object sender, EventArgs e)
            {
                this.Dispose();
            }
    
            private void btnOK_Click(object sender, EventArgs e)
            {
                GetUserLoginState state = new GetUserLoginState();
                //这里便是UI层的BLL,
                //当然也可以在BLL中设计(和登录状态类似的设计)
                if (state.VerifyPassword(txtOriginalPassword.Text.Trim(), UserCurrentID.ID))
                {
                    if (txtNewPassword.Text.Trim() == txtVerifyNewPassword.Text.Trim())
                    {
                        state.ChangePassword(txtVerifyNewPassword.Text.Trim(), UserCurrentID.ID);
                        MessageBox.Show("密码修改成功");
                    }
                    else
                        MessageBox.Show("两次密码不一致");
                }
                else
                    MessageBox.Show("原密码错误");
            }
        }
    View Code

    项目文件:http://pan.baidu.com/s/1sjpUCCP

  • 相关阅读:
    PHP excel读取excel文件转换为数组
    PHP输出xls文件
    proxy_redirect参数的作用
    nginx反向代理批量实现https协议访问
    用lua nginx module搭建一个二维码
    canvas操作图片,进行面板画图,旋转等
    线性表
    什么是闭包
    简单注解扫描的思考
    编写自己的validate校验框架原理(转)
  • 原文地址:https://www.cnblogs.com/wjshan0808/p/3565279.html
Copyright © 2011-2022 走看看