写之前觉得除了数据库难,别的应该挺简单,结果搭建编写C#窗体页面就花了将近一天时间。
反而是连接数据库的操作用时少。
运行环境Visual Studio 2022,.NET6.0,PostgrelSQL 16,DBeaver(好像用到了)
用C#和PostgrelSQL写一个注册登录系统
一、准备工作
确保已经安装了PostgrelSQL和DBeaver(DBeaver好像没用到???)
1.PostgrelSQL
PostgreSL安装教程:QGIS使用PostGIS数据库入门-01 安装postGIS_哔哩哔哩_bilibili
2.DBeaver
安装数据库可视化操作工具,DBeaver:下载网址:https://dbeaver.io/
可以参考DBeaver的安装视频:【准备篇】1.4 安装DBeaver_哔哩哔哩_bilibili
二、C#登录注册页面的搭建
1.页面布局
上图圈起的控件均是两个相同大小的控件重叠在一起。
通过在不同函数中控件名.Visible = true; 控件名.Visible = false;来实现控件的切换。
核心:通过控件的可见与不可见来实现重叠的两个控件的切换。
2.代码思路
(1)注册与登录的切换,退出功能的实现。
(2)密码的可见与隐藏
开始我是用两个外形相同的文本框重叠,联合Button按钮,通过可视与不可视实现密码黑点与非黑点的转换,用两个文本框分别存储可见的密码和不可见的密码,两者内容通过一个字符串实现互相实时同步。
但由于控件之间的关系过于复杂,写完后,功能存在小漏洞,在原来的基础上修改比较麻烦,便决定用同一个文本框,通过函数来实现密码与黑点的转换。
(3)完善其他功能
检测密码与确认密码是否一致,并提示。
检测文本框是否为空,并显示“请输入密码”,“请输入用户名”等相应提示,通过重叠默认隐藏的提示文本框实现的这一功能,检测为空后,自动触发相应函数,实现隐藏文本框可见,密码框隐藏。
重新点击输入后,密码框会重新出现,提示文本框隐藏,鼠标光标自动移动到密码框。
......
三、C#连接到PostgrelSQL数据库
看完下面这篇大概就可以入门了,文章所说的序列在pgAdmin 4页面的左侧:
C#使用Npgsql或SqlClient连接数据库-CSDN博客
下面是文章中几处不太详细,或者由于软件版本不一样改变的地方,作为补充写在下面
1.Npgsql包安装
2.在数据库中新建表
注意应当先新建表,再新建序列,序列是用来针对表的某一列来设置的。
在PostgrelSQL中新建表的时候一定要选择主键,不然创建出来的表格无法编辑。
表中的字段名称最好小写,我之前大写,在C#往数据库里写进数据时报错了。
好像因为PostgreSQL 会将未加引号的字段名转换为小写
3.新建序列
可能由于版本原因,我的是在左侧右键单击“序列”可以新建,与上面文章中不一样。
具体操作看上面的文章链接
4.将C#窗体中的控件与数据库关联
(1)将登录按钮与数据库关联
点击登陆后,会把填写的在TextBox中的用户名和密码,写入数据库。
string connString = "Host=localhost;Port=5432;Username=postgres;Password=123456;Database=GN";//数据库地址
// 使用参数化查询进行检查
string checkSql = "SELECT COUNT(*) FROM \"User\" WHERE Username = @Username";
using (var checkCmd = new NpgsqlCommand(checkSql, conn))
{
checkCmd.Parameters.AddWithValue("@Username", username);
int userCount = Convert.ToInt32(checkCmd.ExecuteScalar());
if (userCount == 0)
{
MessageBox.Show("您输入的用户名不存在!");
}
else
{
// 用户名存在,检查密码
string passwordSql = "SELECT Password FROM \"User\" WHERE Username = @Username";
using (var passCmd = new NpgsqlCommand(passwordSql, conn))
{
passCmd.Parameters.AddWithValue("@Username", username);
#pragma warning disable CS8600 // 禁用CS8622警告
string storedPassword = passCmd.ExecuteScalar() as string;
#pragma warning restore CS8600 // 恢复CS8622警告
if (storedPassword == null)
{
MessageBox.Show("未找到该用户或密码错误!");
}
else if (storedPassword == password)
{
MessageBox.Show("登录成功!");
}
else
{
MessageBox.Show("密码错误!");
}
}
}
}
用于连接数据库的代码意义如下。
string connString = "Host=localhost;Port=5432;Username=postgres;Password=123456;Database=GN";//数据库地址
- Host=localhost:数据库服务器的主机名或IP地址,这里使用的是本地主机(localhost)。
- Port=5432:PostgreSQL 数据库的默认端口是 5432。
- Username=postgres:用于连接数据库的用户名,这里使用的是默认的 "postgres" 用户。
- Password=123456:与用户名对应的密码。
- Database=study:要连接的数据库名,这里是 "GN"。
(2)将注册按钮与数据库关联
点击注册后,会把用户注册时填写的用户名和密码写入数据库
如果把数据库表中字段username作为主键,可以避免有人注册时使用同样的用户名。否则若出现相同的用户名,在登录操作时,会导致数据库无法辨别是哪个用户登陆的。
可能QQ、小红书每个人的账号不同也是类似的原理。
下面代码可以在实际运行中检验错误信息。
string connString = "Host=localhost;Port=5432;Username=postgres;Password=123456;Database=GN";
try
{
using (var conn = new NpgsqlConnection(connString))
{
conn.Open();
//MessageBox.Show("连接到数据库!");
// 获取文本框中的值
string username = tbUsername.Text; // tbUsername是用户名文本框
string password = tbPassword.Text; // tbPassword是密码文本框
// 使用参数化查询插入数据
string sql = "INSERT INTO \"User\" (Username, Password) VALUES (@Username, @Password)";
using (var cmd = new NpgsqlCommand(sql, conn))
{
// 添加参数
cmd.Parameters.AddWithValue("@Username", username);
cmd.Parameters.AddWithValue("@Password", password);
// 执行命令
cmd.ExecuteNonQuery();
MessageBox.Show("注册成功!请登录!");//Data inserted successfully!
}
// 显示数据库连接状态(这里已经是连接状态)
// string connectionState = conn.State.ToString();
// MessageBox.Show(connectionState);
this.Close(); // 关闭当前窗体
LoginForm loginform = new LoginForm();
loginform.Show();
} // 使用 using 块,连接会在这里自动关闭和释放
}
catch (Exception ex)
{
MessageBox.Show("Error connecting to the database: " + ex.Message);
}
(3)完善细微功能
对数据库中的数据进行检索,返回输入密码错误,不存该用户等提示
在注册时,如存在相同的用户名,则提示该用户名已存在,若数据库出现其他故障,则提示系统出错......
四、系统调试
1.删除数据库表中的数据
发现删除按钮是灰色的。
可以用SQL语句执行数据库的修改操作
代码
---全部删除(清空表)
DELETE FROM public."User"
---删除指定元素unwanteduser所在的行
DELETE FROM public."User"
WHERE Username = 'unwanteduser';
2.增加代码健壮性
在不断调试运行过程中检查系统的漏洞,并改正,
比如,不填写完信息,也可以注册。全空注册也可以注册
在把password不为NUll修改后,这一个问题解决。
在系统,注册登陆时,提示报错的弹窗内容进行修改,可以针对性的显示用户的问题,而不是直接显示数据库存在什么问题。
至于为什么要在之前写上这种弹窗,因为这样可以很好的修改程序,在写的时候可以得知具体的错误原因。不过写完后就没必要了。
在控件可视不可视的操作逻辑上存在问题,代码不完善,报错“请输入密码”后,再次点击文本框会消失。需要在【报错文本框点击操作】内加上密码文本框可视操作。
在连续两次点击登录和注册按钮时,密码框和确认密码框都会消失,需要在点击操作内,添加 tbPassword.Visible = true;确保每次点击登录时,该文本框都是可见的。
总之,在运行时乱点窗体,胡乱输入数字,乱登录注册,可以在很大程度上检查出系统存在的漏洞。
五、完善与改进
可以增加限定密码输入长度,限定必须是字母、数字或字符至少包含两种。运用密码哈希和盐值处理等。
可以把“请输入密码”等报错信息写在文本框的Text属性中,ForeColor可以改为红色。这样就不用在CheckTextBoxes.cs文件中写相应代码了。