我是c#和sql的新手,因此非常感谢您的帮助和建议。
我的想法是用sql连接到db,选择密码和电子邮件,然后通过电子邮件(smtp连接)将其发送给想要恢复帐户密码的人。
我的问题是,我试图通过sql为我的c#项目创建密码恢复选项,但出现以下错误:“keyword not supported:'provider'”。
这是我的app.config文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="Sales_and_Inventory_System__Gadgets_Shop_.Properties.Settings.POS_DBConnectionString" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\bin\Debug\POS_DB.mdf;Integrated Security=True;Connect Timeout=30" providerName="System.Data.SqlClient" />
<add name="Restaurant_Management_System.Properties.Settings.SIS_DBConnectionString" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\bin\Debug\SIS_DB.accdb" providerName="System.Data.OleDb" />
<add name="Restaurant_Management_System.Properties.Settings.POS_DBConnectionString" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\bin\Debug\POS_DB.mdf;Integrated Security=True;Connect Timeout=30" providerName="System.Data.SqlClient" />
<add name="Restaurant_Management_System.Properties.Settings.RMS_DBConnectionString" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\bin\Debug\RMS_DB.mdf;Integrated Security=True;Connect Timeout=30" providerName="System.Data.SqlClient" />
</connectionStrings>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite" />
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
</DbProviderFactories>
</system.data></configuration>
这是我的密码恢复类文件:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Net.Mail;
namespace Restaurant_Management_System
{
public partial class frmRecoveryPassword : MetroFramework.Forms.MetroForm
{
String cs = "Provider=Microsoft.ACE.Sql.12.0;Data Source=|DataDirectory|\\SIS_DB.accdb;";
public frmRecoveryPassword()
{
InitializeComponent();
}
private void RecoveryPassword_Load(object sender, EventArgs e)
{
txtEmail.Focus();
}
private void RecoveryPassword_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
frmLogin frm = new frmLogin();
frm.txtUserName.Text = "";
frm.txtPassword.Text = "";
frm.txtUserName.Focus();
frm.Show();
}
private void timer1_Tick(object sender, EventArgs e)
{
Cursor = Cursors.Default;
timer1.Enabled = false;
}
private void metroTile1_Click(object sender, EventArgs e)
{
if (txtEmail.Text == "")
{
MessageBox.Show("Enter your email", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtEmail.Focus();
return;
}
try
{
Cursor = Cursors.WaitCursor;
timer1.Enabled = true;
DataSet ds = new DataSet();
SqlConnection con = new SqlConnection(cs);
con.Open();
SqlCommand cmd = new SqlCommand("SELECT User_Password FROM Registration Where Email = '" + txtEmail.Text + "'", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
con.Close();
if (ds.Tables[0].Rows.Count > 0)
{
MailMessage Msg = new MailMessage();
// Sender e-mail address.
Msg.From = new MailAddress("abcd@gmail.com");
// Recipient e-mail address.
Msg.To.Add(txtEmail.Text);
Msg.Subject = "Your Password Details";
Msg.Body = "Your Password: " + Convert.ToString(ds.Tables[0].Rows[0]["user_Password"]) + "";
Msg.IsBodyHtml = true;
// your remote SMTP server IP.
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Port = 587;
smtp.Credentials = new System.Net.NetworkCredential("abcd@gmail.com", "abcd");
smtp.EnableSsl = true;
smtp.Send(Msg);
MessageBox.Show(("Password Successfully sent " + ("\r\n" + "Please check your mail")), "Thank you", MessageBoxButtons.OK, MessageBoxIcon.Information); this.Hide();
frmLogin LoginForm1 = new frmLogin();
LoginForm1.Show();
LoginForm1.txtUserName.Text = "";
LoginForm1.txtPassword.Text = "";
LoginForm1.ProgressBar1.Visible = false;
LoginForm1.txtUserName.Focus();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void metroTile2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
1条答案
按热度按时间mlnl4t2r1#
你有五(5!)在你的文章正文中的连接字符串。你唯一使用的是在
frmRecoveryPassword
类作为cs
现场。SqlConnection
投诉是因为它至少无法识别一个名称/值对。这是因为它是oledb的连接字符串,而不是sql server。根据您发布的内容,看起来您好像在尝试连接到access数据库。为此,您需要使用
OleDbConnection
. 不过,从评论来看,情况并非如此。您确实要连接到sql server数据库,所以SqlConnection
是正确的,而您的连接字符串是错误的。从您发布的内容开始(而不是从那时起所做的更改),您唯一需要更改的是这一行:
更改为:
这将按中指定的名称检索连接
connectionStringName
把这个给SqlConnection
.请确保使用正确的连接字符串来执行此单击处理程序的操作。
连接字符串
现在让我们检查一下连接字符串。
app.config中的那些看起来是正确的,因为它们具有正确的
providerName
在每个属性中指定的属性。第二个指向access数据库,另外三个指向sqlserver数据库。截图中的那个(来自评论)是错误的。它是一个混合体:你指定了一个
OleDb
提供程序(用于访问)和sql server数据库文件。看起来您从app.config中的第一个连接字符串复制了.mdf文件的路径,并在保存.accdb文件的第二个连接字符串中使用了该路径。SqlConnection
将给您与原始问题相同的例外,因为它不识别"Provider"
键和OleDbConnection
将为您提供“无法识别的数据库格式”。这两种连接都是错误的。无论您使用的是sql server还是access数据库——看起来您的应用程序两者都连接——您都需要确保为该数据库使用正确的连接类型和连接字符串。
现在让我们深入研究一下其他一些问题:
sql注入
不要连接字符串来构造sql。
一定要读一些关于小鲍比table的书。避免sql注入不应该是事后诸葛亮。从一开始就保护您的应用程序。方法是参数化查询。
暂时忽略这个确切查询的危险,下面是您应该做的:
还有其他的
Add
你可以使用重载,但我更喜欢这个,因为它是如何明确的属性,你设置与许多其他重载。我见过有人用错了“db type”,得到的是运行时错误,而不是编译错误,例如传递SqlDbType
当他们使用oracle或mysql时,它会将该值作为object value
参数。你会在许多答案中遇到这些重载的例子。你也会看到
AddWithValue
用了很多——别用了。它的麻烦比它的价值,至少在sql server。密码恢复
这正是我所说的那种质疑的危险。。。
决不以明文形式存储密码。
你不应该给别人发送他们的密码,因为你永远无法找回它。相反,您的数据库应该包含密码的散列。你的
User_Password
列不仅在人眼看来应该像垃圾,在任何用来检索它的系统看来也应该像垃圾。“密码恢复”是一个不准确的术语,当你做得对。处理忘记密码的现代实践实际上是“访问恢复”,它们通常涉及允许您提供新密码的短期令牌。
像密码散列和访问恢复过程这样的主题都有很好的文档记录,所以我将不再深入讨论它们。