一.构建两层架构(DAL,UI)
我认为两层是三层的雏形,先把业务逻辑层放在DAL中学习我所谓的两层架构。
人力资源管理系统搭建两层:
UI层是显示层,用于界面的显示,如同程序的入口,当然配置文件要放在UI层,在UI层建一个CommonHelper.cs类,用于实现一些公用的方法,如MD5算法。因为显示层即会经常调用数据传输对象Model,又会调用DAL层的方法,所以要添加Model,DAL引用;
DAL层是数据访问层,它是一个类库,要经常与数据库进行交互,所以与数据库交互的常用方法类SqlHelper类放在DAL层中。因为会经常调用数据传输对象Model,所以要添加Model引用;
Model不是层,只是数据传输对象的一个类库
二.DAL层中的几个方法
1.DataGrid的数据绑定
<DataGrid DockPanel.Dock="Top" Name="grid" AutoGenerateColumns="False" SelectionChanged="grid_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="用户编号" Width="300" Binding="{Binding Id}"></DataGridTextColumn>
<DataGridTextColumn Header="用户姓名" Width="200" Binding="{Binding OperatorName}"></DataGridTextColumn>
<DataGridTextColumn Header="用户密码" Width="300" Binding="{Binding OperatorPwd}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
this.grid.ItemsSource = OperatorDAL.GetAll();
2.获取表中的所有数据,通过循环,将这些行数据以对象形式存放数组,可以在前台通过DataGrid.ItemsSourse绑定数据源
//获取所有数据
public static Operator[] GetAll()
{
DataTable dt = SqlHelper.ExecuteDataTable("select * from T_Operator");
Operator[] opers =new Operator[dt.Rows.Count];
for (int i = 0; i < dt.Rows.Count; i++)
{
Operator oper = new Operator();
oper.Id = (Guid)dt.Rows[i]["Id"];
oper.OperatorName = (string)dt.Rows[i]["OperatorName"];
oper.OperatorPwd=(string)dt.Rows[i]["OperatorPwd"];
opers[i] = oper;
}
return opers;
}
三.密码MD5处理
1.密码以明文保存的问题:容易泄露用户常用密码,2012年的互联网密码泄露风波;
2.MD5算法是一种散列(hash)算法(摘要算法,指纹算法),不是一种加密算法。任何长度的任意内容都可以用MD5计算出散列值。
3.MD5算法不可逆,也就是只能得到内容对应的MD5值,无法由MD5值反推内容,对于不同的内容产生相同MD5值的概率非常非常非常低!
4.Password字段保存用户输入密码的MD5值,这样系统管理员,黑客也不知道用户的密码是什么。这样也就避免了用户的其他系统密码被利用的问题。
5.网上什么MD5破解,看着貌似成功,纯属闲扯,那是一种穷举(常用的MD5存储,进行查询),不能说就能反推。所以在很多的网站注册,经常会提醒用户输入非常复杂的密码。
6.MD5只能碰撞,不能逆向运算。所以很多网站在找回密码这一功能都是问题提醒,重置密码,不能把你的原始密码发给你。
7.虽然多次提醒用户使用复杂的密码,但是用户还是不按照要求,还是输入非常简单的密码,如何提高密码的安全性?MD5加盐(理论上是不可逆,比双重MD5等安全),即在用户输入的密码基础上系统自动添加一些字符,如用户输入abcd,系统录入的时候abcd#$FW!
一个常用的MD5算法:
//MD5算法
public static string GetMD5(string sDataIn)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] bytValue, bytHash;
bytValue = System.Text.Encoding.UTF8.GetBytes(sDataIn);
bytHash = md5.ComputeHash(bytValue);
md5.Clear();
string sTemp = "";
for (int i = 0; i < bytHash.Length; i++)
{
sTemp += bytHash[i].ToString("X").PadLeft(2, '0');
}
return sTemp.ToLower();
}
四.“MD5加盐”
1.使用”MD5加盐”方式实现用户的登陆功能(即在用户输入的密码再拼接固定的盐,再MD5加密,与数据库中的MD5密码比较,如果相同则密码无误,否则,登陆失败)
private void bt_Login_Click_1(object sender, RoutedEventArgs e)
{
string name = this.txt_UserName.Text.Trim();
string pwd = this.pwd.Password;
string MD5pwd = CommonHelper.GetMD5(pwd + "love&@iew");
if (name == "" || pwd == "")
{
MessageBox.Show("登陆信息没有填写完整!");
}
else
{
Operator oper = OperatorDAL.GetOperatorByName(name);
if (oper == null)
{
MessageBox.Show("不存在该用户,登陆失败");
}
else
{
if (MD5pwd == oper.OperatorPwd)
{
ListUIWindow list = new ListUIWindow();
list.ShowDialog();
this.Close();
}
else
{
MessageBox.Show("密码错误!");
}
}
}
}
2.使用“MD5加盐”实现用户的录入功能,在录入前要判断用户名不能重复!
private void Button_Click(object sender, RoutedEventArgs e)
{
string name=this.txt_UserName.Text.Trim();
string pwd=this.txt_Pwd.Text.Trim();
Operator opera=OperatorDAL.GetOperatorByName(name);
if(opera!=null)
{
MessageBox.Show("用户名已存在!");
}
else
{
Operator oper = new Operator();
oper.OperatorName = name;
string MD5pwd = CommonHelper.GetMD5(pwd + "love&@iew");
oper.OperatorPwd = MD5pwd;
OperatorDAL.InsertData(oper);
bindDataGrid();
}
}
DAL层判断用户名是否重复的方法:
//写一个方法(通过DataTable给Operator对象赋值,并返回该对象)
public static Operator TableToOper(DataTable table)
{
Operator oper = new Operator();
oper.Id = (Guid)table.Rows[0]["Id"];
oper.OperatorName = (string)table.Rows[0]["OperatorName"];
oper.OperatorPwd = (string)table.Rows[0]["OperatorPwd"];
return oper;
}
//通过用户名获取用户
public static Operator GetOperatorByName(string name)
{
DataTable dt= SqlHelper.ExecuteDataTable(@"select * from T_Operator where OperatorName=@OperatorName",
new SqlParameter("@OperatorName",name));
if (dt.Rows.Count <= 0)
{
return null;
}
else if (dt.Rows.Count > 1)
{
throw new Exception("存在重名用户!");
}
else
{
return TableToOper(dt);
}
}