前言
使用.Net 平台来创建一个应用程序,包含验证登录账号密码功能,验证验证码功能,记住账号功能以及根据登录账号权限不同,跳转到不同界面的功能。
数据库使用sqlserver数据库
一、问题描述
- 连接数据库,实现对数据的读取操作
- 管理人员使用账号与密码登录系统。本系统的管理员包括 3 种类型
- 若管理员的登录失败次数达到 3 次,那么系统应显示并且同时包含字母与数字的4位验证码,验证码字符输入正确方可登录。
- 若管理员的登录失败次数达到 3 次,那么系统应显示并且同时包含字母与数字的4位验证码,验证码字符输入正确方可登录。
- 若选择记住密码,下次登录时直接显示上次输入的账号和密码,
二、解题思路
1.登录界面设计
2.数据库
此处的数据库连接代码可能不太实用了,已经更新了更加优雅的方法见下面链接
.Net连接SQL Server数据库的优雅方式(巨详细)
需要连接SQL server数据库,则需要创建一个用于链接数据库的类,在登录界面代码中调用。
3.登录
登录功能的大致内容为
- 验证登录账号和密码
- 获取登录账号的权限(以数字代表权限,一共有三种权限,分别是1,2,3)
- 若验证错误次数超过三次,则生成验证码
- 判断用户是否勾选记住账号
三、功能实现
1.链接数据库
创建一个server_connection1.cs的类文件,用于链接数据库
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace OlympicManagement
{
class server_connection1
{
public SqlConnection connection()
{
string conStr = "Server = localhost; Database = text; User ID = sa; Password = 123456; Trusted_Connection = False;";
SqlConnection sqlcon = new SqlConnection(conStr);
sqlcon.Open();
return sqlcon;
}
public SqlCommand command(string sql)
{
SqlCommand sqlcom = new SqlCommand(sql, connection());
return sqlcom;
}
//用于delete update insert 返回受影响行数
public int Excute(string sql)
{
return command(sql).ExecuteNonQuery();
}
// 用于select,返回SqldataReader对象,包含select到的数据
public SqlDataReader read(string sql)
{
return command(sql).ExecuteReader();
}
}
}
2.验证登录信息功能的函数
private bool islogin()//验证登录账号密码以及验证码
{
if (textBox1.Text == "" || textBox2.Text == "")
{
MessageBox.Show("用户名和密码不能为空", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
else
{
//链接数据库验证
string sql = "select * from Staff where LoginID = '" + textBox1.Text + "' and Password = '" + textBox2.Text + "'";
server_connection1 ser = new server_connection1();
IDataReader reader = ser.read(sql);
if (reader.Read())
{
//获取登录账号类型
login_role = reader["RoleID"].ToString().Trim();
Console.WriteLine(login_role);
//查询到结果允许登录
return true;
}
else
{
MessageBox.Show("密码或用户名不正确", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
reader.Close();
}
}
3.实现验证码功能
写一个类用于创建验证码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OlympicManagement
{
class VrefiyCode
{
///生成随机验证字符串
public static string CreateRandomCode(int CodeLength)
{
int rand;
char code;
string randomCode = String.Empty;//随机验证码
//生成特定长度的验证码
Random random = new Random();
for (int i = 0; i < CodeLength; i++)
{
rand = random.Next();
if (rand % 3 == 1)
{
code = (char)('A' + (char)(rand % 26));//随机取字母
}
else if (rand % 3 == 2)
{
code = (char)('a' + (char)(rand % 26));
}
else
{
code = (char)('0' + (char)(rand % 10));
}
randomCode += code.ToString();
}
return randomCode;
}
///创建图片
public static void CreateImage(string strValidCode, PictureBox pbox)
{
try
{
int RandAnlge = 45;//旋转角度
int MapWidth = (int)(strValidCode.Length * 21);
Bitmap map = new Bitmap(MapWidth, 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 = strValidCode.ToCharArray();//拆散字符串组成单字符数组
//文字居中
StringFormat format = new StringFormat(StringFormatFlags.NoWrap);
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
//定义颜色
Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple, Color.Green };
//定义字体
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);//字体样式,大小
Brush b = new System.Drawing.SolidBrush(c[cindex]);
Point dot = new Point(16, 16);
float angle = rand.Next(-RandAnlge, RandAnlge);//旋转度数
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);//移动光标到指定位置
}
pbox.Image = map;
}
catch
{
MessageBox.Show("验证图片创建错误");
}
}
}
}
更新验证码的方法
因为验证码验证失败后,需要更新,所以创建一个更新验证码的方法
private void UpdateValidCode()
{
strValidCode = VrefiyCode.CreateRandomCode(ValidCodeLength);//生成随机验证码
if (strValidCode == "") return;
VrefiyCode.CreateImage(strValidCode, pbox1);//创建验证码图片
}
写一个方法调用验证码类和验证验证码
private bool isvalidcode()
{
string validcode = textBox3.Text.Trim();
if (String.IsNullOrEmpty(validcode) != true)//验证码不为空
{
if (validcode.ToLower() == strValidCode.ToLower())
{
UpdateValidCode();//启动验证吗验证
textBox3.Text = "";
textBox3.Focus();
return true;
}
else
{
MessageBox.Show("验证失败", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
UpdateValidCode();//更新验证码
textBox3.Text = "";
textBox3.Focus();
return false;
}
}
else
{
MessageBox.Show("请输入验证码", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
UpdateValidCode();//更新验证码
textBox3.Text = "";
textBox3.Focus();
return false;
}
}
4.保存账号及密码功能的实现
在APP.config中先创建键值对用于储存复选框状态以及记录账号信息
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key ="remenberme" value=""/>
<add key ="username" value=""/>
<add key ="userpasswd" value=""/>
<add key ="roleID" value=""/>
</appSettings>
</configuration>
写一个用于记录账号信息的方法
private void remenberme()
{
//提取信息
string usertext = textBox1.Text.Trim();
string userpasswd = textBox2.Text.Trim();
Configuration cf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//根据复选框状态储存账号信息
if (checkBox1.Checked)
{
cf.AppSettings.Settings["username"].Value = usertext;
cf.AppSettings.Settings["userpasswd"].Value = userpasswd;
cf.AppSettings.Settings["remenberme"].Value = "true";
}
else
{
cf.AppSettings.Settings["remenberme"].Value = "false";
}
cf.Save();
}
在窗体加载的同时写入储存的登录信息
private void Form_Login_Load(object sender, EventArgs e)
{
if (ConfigurationManager.AppSettings["remenberme"].Equals("true"))
{
textBox1.Text = ConfigurationManager.AppSettings["username"];
textBox2.Text = ConfigurationManager.AppSettings["userpasswd"];
checkBox1.Checked = true;
}
}
5.在点击登录时实现这些功能
验证登录信息
private bool islogin()
{
if (textBox1.Text == "" || textBox2.Text == "")
{
MessageBox.Show("用户名和密码不能为空","提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);
return false;
}
else
{
//链接数据库验证
string sql = "select * from Staff where LoginID = '" + textBox1.Text + "' and Password = '" + textBox2.Text + "'";
server_connection1 ser = new server_connection1();
IDataReader reader = ser.read(sql);
if (reader.Read())
{
//获取登录账号类型
login_role = reader["RoleID"].ToString().Trim();
Console.WriteLine(login_role);
//查询到结果允许登录
return true;
}
else
{
MessageBox.Show("密码或用户名不正确","提示",MessageBoxButtons.OK,MessageBoxIcon.Error);
return false;
}
reader.Close();
}
}
登录功能的实现
此处验证成功之后提示成功登录,跳转界面等功能不是此文的终点内容,后文会有对此部分的补充完善
private void btn_Login_Click(object sender, EventArgs e)
{
remenberme();
login_time += 1;
if (login_time <=3)//登录次数小于3次,无需验证码验证
{
if (islogin())
{
MessageBox.Show("登录成功");
}
else
{
if (login_time == 3)
{
UpdateValidCode();
}
}
}
else//登录次数大于3次,需验证码验证
{
if (isvalidcode() && islogin())
{
MessageBox.Show("登录成功");
}
}
}
四、登录页面完整代码:
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.Configuration;
namespace OlympicManagement
{
public partial class Form_Login : Form
{
public Form_Login()
{
InitializeComponent();
}
int login_time = 0;
public static string login_role;
private const int ValidCodeLength = 4;//验证码长度
private String strValidCode = "";//验证码
private bool islogin()
{
if (textBox1.Text == "" || textBox2.Text == "")
{
MessageBox.Show("用户名和密码不能为空","提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);
return false;
}
else
{
//链接数据库验证
string sql = "select * from Staff where LoginID = '" + textBox1.Text + "' and Password = '" + textBox2.Text + "'";
server_connection1 ser = new server_connection1();
IDataReader reader = ser.read(sql);
if (reader.Read())
{
//获取登录账号类型
login_role = reader["RoleID"].ToString().Trim();
Console.WriteLine(login_role);
//查询到结果允许登录
return true;
}
else
{
MessageBox.Show("密码或用户名不正确","提示",MessageBoxButtons.OK,MessageBoxIcon.Error);
return false;
}
reader.Close();
}
}
private void btn_Login_Click(object sender, EventArgs e)
{
remenberme();
login_time += 1;
if (login_time <=3)//错误次数小于3
{
if (islogin())
{
MessageBox.Show("登录成功");
}
else
{
if (login_time == 3)
{
UpdateValidCode();
}
}
}
else
{
if (isvalidcode() && islogin())
{
MessageBox.Show("登录成功");
}
}
}
//更新验证码函数
private void UpdateValidCode()
{
strValidCode = VrefiyCode.CreateRandomCode(ValidCodeLength);//生成随机验证码
if (strValidCode == "") return;
VrefiyCode.CreateImage(strValidCode, pbox1);//创建验证码图片
}
//验证验证码
private bool isvalidcode()
{
string validcode = textBox3.Text.Trim();
if (String.IsNullOrEmpty(validcode) != true)//验证码不为空
{
if (validcode.ToLower() == strValidCode.ToLower())
{
UpdateValidCode();//启动验证吗验证
textBox3.Text = "";
textBox3.Focus();
return true;
}
else
{
MessageBox.Show("验证失败", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
UpdateValidCode();//启动验证吗验证
textBox3.Text = "";
textBox3.Focus();
return false;
}
}
else
{
MessageBox.Show("请输入验证码", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
UpdateValidCode();//启动验证吗验证
textBox3.Text = "";
textBox3.Focus();
return false;
}
}
private void remenberme()
{
string usertext = textBox1.Text.Trim();
string userpasswd = textBox2.Text.Trim();
Configuration cf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (checkBox1.Checked)
{
cf.AppSettings.Settings["username"].Value = usertext;
cf.AppSettings.Settings["userpasswd"].Value = userpasswd;
cf.AppSettings.Settings["remenberme"].Value = "true";
}
else
{
cf.AppSettings.Settings["remenberme"].Value = "false";
}
cf.Save();
}
private void Form_Login_Load(object sender, EventArgs e)
{
if (ConfigurationManager.AppSettings["remenberme"].Equals("true"))
{
textBox1.Text = ConfigurationManager.AppSettings["username"];
textBox2.Text = ConfigurationManager.AppSettings["userpasswd"];
checkBox1.Checked = true;
}
}
private void btn_Exit_Click(object sender, EventArgs e)
{
remenberme();
this.Close();
}
}
}
五、运行结果截图
正确账号密码登录
错误账号,错误密码登录
错误3次后显示验证码
验证码错误
验证码正确
记住密码后登录
总结
以上就是此文章记录的内容,是最近在做的一个小项目的部分内容,简单介绍了并实现常见的登录功能。
鄙人才疏学浅,若有错误和缺陷还请欢迎大家留言讨论,多多指教,期待于CSDN的各位一起进步!