初学C#Windows窗体程序时,做个简单的“登录”是再简单不过的了。像下面这样的,功能稍理想了吧?
2019年9月21日 18:28:19
有后台数据库,有验证码,数据库中密码是密文(如图所示:数据库中表数据是32位MD5加密的……)
下面讲解如何实现。
步骤:
1、创建相应的数据库,建立表,设置字段及其属性,设计触发器
2、创建WinForm窗体程序
3、设计窗体
4、编辑代码
程序流程:
1、用户输入账号、密码,验证码
2、提交
3、连接数据库、查询密码
4、成功匹配对应账号密码则跳转到指定窗体,失败则返回登陆窗体
要点:
1、前台界面如何设计?
ANS:使用label、textbox、button控件
2、后台数据库中密码字段如何加密为密文?
ANS:使用简单的MD5加密算法
3、前台textbox中的数据如何和后台数据库中的密文匹配?
ANS:将前台textbox中的数据同样加密,与后台密文匹配。(加密算法具有唯一性、单向性)
环境:
- 机器:windows 7 64 bit
- IDE:Visual Studio 2012 Ultimate
- 数据库:SQL Server 2005
1、数据库部分
数据库使用两张表,分别存储用户登录信息及用户注册信息。
1.1 表idpassword
|number|id|password|
|------|--|--------|
1.2 表registerinformation
| number| id | password | name | mail |
|-------|----|----------|------|------|
1、3 触发器 trg_EncryptPwd
--sql触发器,自动加密前台传入的密码字段
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER TRIGGER [trg_EncryptPwd]
//这里注意,初次建立触发器,请将ALTER修改为CREATE
ON [dbo].[idpassword]
AFTER INSERT,UPDATE
AS
BEGIN
IF(UPDATE(password))
BEGIN
DECLARE @uid varchar(32)
DECLARE @pwd varchar(32)
-- 获取用户ID和密码
SELECT @uid=id,@pwd=password FROM inserted
-- 更新密码
UPDATE idpassword SET password = dbo.MD5(@pwd,32) WHERE id = @uid
END
END
-- 注册用户时,自动将用户密码加密。
2、前台视图
使用label、textbox、button控件。
3、代码
代码部分包含6位验证码(区分大小写)的生成、WinForm窗体的跳转、前台textbox中密码的加密、
前台输入的账号与后台数据库中的数据的匹配……
登录窗体代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Security.Cryptography;
/* 程序内容:实现简单登陆程序,使用账号,密码登录。
* 窗体:
* Login.cs :
* 控件: label1 账号: label2 密码:
* texId 账号 texPwd 密码
* button1 登陆 button2 注册
*
* Register.cs
* 控件: label1 账号: label2 密码:label3 姓名: label4 邮箱:
* texId 账号 texPwd 密码 texName 姓名 texMail 邮箱
* button1 注册 button2 重置
*
* 作者:zhoujl
* -------------------------2017年10月25日09:03:38----------------------
*
*/
namespace LoginDateBase
{
public partial class Login : Form
{
//随机码的长度
private const int iVerifyCodeLength = 6;
//随机码
private String strVerifyCode = "";
public Login()
{
InitializeComponent();
UpdateVerifyCode();
}
/// <summary>
/// 更新验证码
/// </summary>
private void UpdateVerifyCode()
{
strVerifyCode = CreateRandomCode(iVerifyCodeLength);
CreateImage(strVerifyCode);
}
/// <summary>
/// 创建随机码图片
/// </summary>
/// <param name="strVerifyCode"></param>
private void CreateImage(string strVerifyCode)
{
try
{
int iRandAngle = 45; //随机转动角度
int iMapWidth = (int)(strVerifyCode.Length * 21);
Bitmap map = new Bitmap(iMapWidth, 28); //创建图片背景
Graphics graph = Graphics.FromImage(map);
graph.Clear(Color.AliceBlue);//清除画面,填充背景
graph.DrawRectangle(new Pen(Color.Black, 0), 0, 0, map.Width - 1, map.Height - 1);//画一个边框
graph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;//模式
Random rand = new Random();
//背景噪点生成
Pen blackPen = new Pen(Color.LightGray, 0);
for (int i = 0; i < 50; i++)
{
int x = rand.Next(0, map.Width);
int y = rand.Next(0, map.Height);
graph.DrawRectangle(blackPen, x, y, 1, 1);
}
//验证码旋转,防止机器识别
char[] chars = strVerifyCode.ToCharArray();//拆散字符串成单字符数组
//文字距中
StringFormat format = new StringFormat(StringFormatFlags.NoClip);
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
//定义颜色
Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
//定义字体
string[] font = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
for (int i = 0; i < chars.Length; i++)
{
int cindex = rand.Next(7);
int findex = rand.Next(5);
Font f = new System.Drawing.Font(font[findex], 13, System.Drawing.FontStyle.Bold);//字体样式(参数2为字体大小)
Brush b = new System.Drawing.SolidBrush(c[cindex]);
Point dot = new Point(16, 16);
float angle = rand.Next(-iRandAngle, iRandAngle);//转动的度数
graph.TranslateTransform(dot.X, dot.Y);//移动光标到指定位置
graph.RotateTransform(angle);
graph.DrawString(chars[i].ToString(), f, b, 1, 1, format);
graph.RotateTransform(-angle);//转回去
graph.TranslateTransform(2, -dot.Y);//移动光标到指定位置
}
pictureBox1.Image = map;
}
catch (ArgumentException)
{
MessageBox.Show("创建图片错误。");
}
}
/// <summary>
/// 创建验证码
/// </summary>
/// <param name="iLength"></param>
/// <returns></returns>
private string CreateRandomCode(int iLength)
{
int rand;
char code;
string randomCode = String.Empty;
//生成一定长度的验证码
System.Random random = new Random();
for (int i = 0; i < iLength; i++)
{
rand = random.Next();
if (rand % 3 == 0)
{
code = (char)('A' + (char)(rand % 26));
}
else
{
code = (char)('0' + (char)(rand % 10));
}
randomCode += code.ToString();
}
return randomCode;
}
private void Login_Load(object sender, EventArgs e)
{
this.ActiveControl = this.txtId;
}
private void Login_Paint(object sender, PaintEventArgs e)
{
}
/// <summary>
/// 登陆
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
//连接数据库为SQL Server 2005
//定义链接字符串
string connString = "server=.;user id=sa;password=sa;database=register";
//1.创建连接对象
SqlConnection conn = null;
try
{
conn = new SqlConnection(connString);
}
catch (Exception e1)
{
e1.ToString();
MessageBox.Show("创建连接对象出错");
}
//md5 32位加密
byte[] result = Encoding.Default.GetBytes(this.txtPwd.Text.Trim()); //输入密码的文本框
MD5 md5 = new MD5CryptoServiceProvider();
byte[] output = md5.ComputeHash(result);//加密后的登陆明文密码
this.txtPwd.Text = BitConverter.ToString(output).Replace("-", ""); //为输出加密文本的文本框
string sqlLog = "select * from idpassword where id='"
+ txtId.Text.Trim() + "'and password='" + this.txtPwd.Text + "' ";
try
{
//2.打开连接
conn.Open();
}
catch (Exception e2)
{
e2.ToString();
MessageBox.Show("数据库连接出错");
}
if (txtId.Text.Equals("") || txtPwd.Text.Equals(""))//账号,密码为空
{
MessageBox.Show("请输入账号密码");
}
else if (textBox1.Text.Equals("") || !textBox1.Text.Equals(strVerifyCode))//验证码为空或错误
{
MessageBox.Show("验证码错误");
}
else
{
//数据库tra-sql语句
//3.执行查询
SqlCommand cmdL = new SqlCommand(sqlLog, conn);
//从数据库读一行
SqlDataReader sread = cmdL.ExecuteReader();
int count = 0;
while (sread.Read())
{
count++;
}
//4.关闭连接
conn.Close();
if (count > 0)
{
MessageBox.Show("登陆成功");
//登陆成功则跳转至新的窗体
Search search = new Search();
//查询窗口
search.Show();
}
else
{
MessageBox.Show("登录失败");
}
}
}
private void button2_Click(object sender, EventArgs e)//注册
{
Register form2 = new Register();
form2.Show();
}
/// <summary>
/// 刷新验证码
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)//更换验证码
{
UpdateVerifyCode();
}
}
}
注册窗体代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.Sql;
namespace LoginDateBase
{
public partial class Register : Form
{
public Register()
{
InitializeComponent();
}
//清空输入
public void c()
{
txtIdR.Text = "";
txtPwdR.Text = "";
txtName.Text = "";
txtMail.Text = "";
}
private void Registe_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
//输入不能为空
if (txtIdR.Text == "" | txtPwdR.Text == "" | txtName.Text == "" | txtMail.Text == "")
{
MessageBox.Show("请输入完整信息");
return;
}
///LoginId不能为重复
//定义链接字符串
string connString = "server=.;user id=sa;password=sa;database=register";
//1.创建连接对象
SqlConnection conn = new SqlConnection(connString);
//组合sql查询语句
string sqlSelect = "select id from registerinformation where id='" + txtIdR.Text.Trim() + "'";
SqlCommand cmd1 = new SqlCommand(sqlSelect, conn);
//2.打开连接
//3.执行查询
conn.Open();
object result1 = cmd1.ExecuteScalar();
//判断账号是否重复
if (result1 != null)
{
MessageBox.Show("该账户已被注册");
conn.Close();
return;
}
//4.关闭连接
conn.Close();
//添加注册信息SQL语句
string sql = "insert into registerinformation(id,password,name,mail)";
sql += "values('{0}','{1}','{2}','{3}')";
sql = string.Format(sql, txtIdR.Text, txtPwdR.Text, txtName.Text, txtMail.Text);
SqlCommand cmd = new SqlCommand(sql, conn);
//打开连接
conn.Open();
//执行操作
int reslt = cmd.ExecuteNonQuery();
conn.Close();
//清空输入
c();
//注册成功
MessageBox.Show("注册成功");
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
c();
txtIdR.Focus();
}
}
}
后记:
时间仓促,本人水平也有限,若各位读者发现错误欢迎批评指正!