关键字:尝试打开sql连接时的“provider”

o4tp2gmn  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(422)

我是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();
        }
    }
}
mlnl4t2r

mlnl4t2r1#

你有五(5!)在你的文章正文中的连接字符串。你唯一使用的是在 frmRecoveryPassword 类作为 cs 现场。 SqlConnection 投诉是因为它至少无法识别一个名称/值对。这是因为它是oledb的连接字符串,而不是sql server。
根据您发布的内容,看起来您好像在尝试连接到access数据库。为此,您需要使用 OleDbConnection . 不过,从评论来看,情况并非如此。您确实要连接到sql server数据库,所以 SqlConnection 是正确的,而您的连接字符串是错误的。
从您发布的内容开始(而不是从那时起所做的更改),您唯一需要更改的是这一行:

SqlConnection con = new SqlConnection(cs);

更改为:

// Pick one of the three names in app.config that refers to a SQL Server database.
// I chose the first one for this example.
string connectionStringName = "Sales_and_Inventory_System__Gadgets_Shop_.Properties.Settings.POS_DBConnectionString";

string connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;

SqlConnection con = new SqlConnection(connectionString);

这将按中指定的名称检索连接 connectionStringName 把这个给 SqlConnection .
请确保使用正确的连接字符串来执行此单击处理程序的操作。

连接字符串

现在让我们检查一下连接字符串。
app.config中的那些看起来是正确的,因为它们具有正确的 providerName 在每个属性中指定的属性。第二个指向access数据库,另外三个指向sqlserver数据库。
截图中的那个(来自评论)是错误的。它是一个混合体:你指定了一个 OleDb 提供程序(用于访问)和sql server数据库文件。看起来您从app.config中的第一个连接字符串复制了.mdf文件的路径,并在保存.accdb文件的第二个连接字符串中使用了该路径。 SqlConnection 将给您与原始问题相同的例外,因为它不识别 "Provider" 键和 OleDbConnection 将为您提供“无法识别的数据库格式”。这两种连接都是错误的。
无论您使用的是sql server还是access数据库——看起来您的应用程序两者都连接——您都需要确保为该数据库使用正确的连接类型和连接字符串。
现在让我们深入研究一下其他一些问题:

sql注入

不要连接字符串来构造sql。
一定要读一些关于小鲍比table的书。避免sql注入不应该是事后诸葛亮。从一开始就保护您的应用程序。方法是参数化查询。
暂时忽略这个确切查询的危险,下面是您应该做的:

SqlCommand cmd = new SqlCommand("SELECT User_Password FROM Registration WHERE Email = @Email");
                                                                                   // ^^^^^^ parameter
cmd.Parameters.Add(new SqlParameter
{
    Name = "@Email",
    SqlDbType = SqlDbType.NVarChar,
    Size = 100, // or whatever length your Email column is.
    Value = txtEmail.Text
         // ^^^^^^^^^^^^^ paramter's value
});

还有其他的 Add 你可以使用重载,但我更喜欢这个,因为它是如何明确的属性,你设置与许多其他重载。我见过有人用错了“db type”,得到的是运行时错误,而不是编译错误,例如传递 SqlDbType 当他们使用oracle或mysql时,它会将该值作为 object value 参数。你会在许多答案中遇到这些重载的例子。
你也会看到 AddWithValue 用了很多——别用了。它的麻烦比它的价值,至少在sql server。

密码恢复

这正是我所说的那种质疑的危险。。。
决不以明文形式存储密码。
你不应该给别人发送他们的密码,因为你永远无法找回它。相反,您的数据库应该包含密码的散列。你的 User_Password 列不仅在人眼看来应该像垃圾,在任何用来检索它的系统看来也应该像垃圾。
“密码恢复”是一个不准确的术语,当你做得对。处理忘记密码的现代实践实际上是“访问恢复”,它们通常涉及允许您提供新密码的短期令牌。
像密码散列和访问恢复过程这样的主题都有很好的文档记录,所以我将不再深入讨论它们。

相关问题