类型' System.Data.OleDb.OleDbException'的未处理异常发生了

时间:2016-03-06 02:54:16

标签: c# oledb

我正在创建一个程序,用户将登录系统,但会出现这样的错误,

我还使用c#编程语言和我的数据库中的Ms Access。

这是我的整个代码。

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Data.OleDb;
using System.Drawing.Drawing2D;

namespace Shakeys_Inventory_System
{
    public partial class frmLogin : Form
    {
        private OleDbConnection cn = new OleDbConnection();

        public frmLogin()
        {
            //SplashScreen
            Thread t = new Thread(new ThreadStart(SplashStart));
            t.Start();
            Thread.Sleep(2500);

            InitializeComponent();

            this.BackColor = Color.White;
            panel1.BackColor = Color.FromArgb(25, Color.Black);

            t.Abort();

            cn.ConnectionString = (@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C: \Users\Raphael\Documents\Visual Studio 2015\Projects\Shakeys_Inventory_System\Shakeys_Inventory_System\ShakeysDatabase.accdb");
        }

        //Blurred Panel *START
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.DrawLine(Pens.Yellow, 0, 0, 100, 100);
        }

        public void SplashStart()
        {
            Application.Run(new frmSplashScreen());
        }

        public void DrawPath(Pen pen, GraphicsPath path)
        { 

        }

        private void frmLogin_Load(object sender, EventArgs e)
        {

        }

        //Button Login Start
        private void btn_Login_Click(object sender, EventArgs e)
        {
            cn.Open();
            OleDbCommand cm = new OleDbCommand();
            cm.Connection = cn;
            cm.CommandText = "Select * from UsernameInfo where Username = '" +txt_Username.Text+ "' and password = '"+txt_Password.Text+"'";
            OleDbDataReader odr = cm.ExecuteReader();
            int cnt = 0;
            while (odr.Read())
            {
                cnt++;
            }
            if (cnt == 1)
            {
                this.Hide();
                frmHomepage fhp = new frmHomepage("Welcome:"+ txt_Username.Text);
                fhp.ShowDialog();
            }
            else
            {
                MessageBox.Show("Username or Password is Incorrect!", "ERROR!",MessageBoxButtons.OK,MessageBoxIcon.Error,MessageBoxDefaultButton.Button1);
            }
            cn.Close();
        }

        //Button Quit *Start
        private void btn_Quit_Click(object sender, EventArgs e)
        {
            DialogResult Result1 = MessageBox.Show("Do you want to CLOSE the program?", "Warning!",MessageBoxButtons.YesNo,MessageBoxIcon.Question);

            if (Result1 == DialogResult.Yes)
            {
                Application.Exit();
            }
        }
    }
}

顺便说一句,我在MSACESS中创建了自己的数据库并将路径文件复制到其中并插入我的,

cn.ConnectionString = (@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C: \Users\Raphael\Documents\Visual Studio 2015\Projects\Shakeys_Inventory_System\Shakeys_Inventory_System\ShakeysDatabase.accdb");

路径文件是对的,我的查询也是对的,表也是,我的问题是,为什么我收到错误?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

? character是您想要参数

的占位符
cm.CommandText = "Select * from UsernameInfo where Username = ? and password = ?";

现在,按照编写查询的顺序添加参数

cm.Parameters.AddWithValue( "parmUserName", txt_Username.Text );
cm.Parameters.AddWithValue( "parmPassword", txt_Password.Text );

现在执行您的查询

OleDbDataReader odr = cm.ExecuteReader();

如果有人要在文本中加入'字符,它会预先关闭引用的连接并将其余部分关闭,从而导致错误。

此外,您的路径还有一个额外的空格“C:\”而不是“C:\”

<强>反馈

澄清“?”。如果您连接一个字符串来构建一个查询,那么您可以通过sql-injection进行广泛的操作。 “?” (字面意思是?字符)充当占位符的含义。我将为查询命令提供“参数”,我希望你把第一个参数放在第一个“?”的位置。找到,第二个参数位于第二个“?”。

所以,让我们来看看你的原始查询

"Select * from UsernameInfo where Username = '" +txt_Username.Text+ "' and password = '"+txt_Password.Text+"'";

并且假设我为

输入了以下值
txt_Username.Text = "O'Brien"
txt_Password.Text = "it's ok"

您生成的sql命令实际上将变为

Select * from UsernameInfo where Username = 'O'Brien' and password = 'it's ok'

请注意用户和密码VALUES周围不匹配的报价余额。

使用“?”作为占位符

Select * from UsernameInfo where Username = ? and password = ?

cm.Parameters.AddWithValue( "parmUserName", txt_Username.Text );
cm.Parameters.AddWithValue( "parmPassword", txt_Password.Text );

将成为

Select * from UsernameInfo where Username = [value of first parameter] and password = [value of second parameter]

引擎会识别字符串,数字,日期等数据类型并为您处理。您可以更明确地声明参数的TYPE,但它通常会为您检测类型。

现在,对于SQL-Injection,并不是通过访问曝光,但通常是“;”分号表示一个sql语句的结束并允许另一个。有人找出了你的桌子的名字。在SQL中,双破折号被视为注释,并忽略它。同样,这只是一个样本。您的查询是通过构建字符串

构建的
Select * from UsernameInfo where Username = 'O'Brien' and password = 'it's ok'

和txtUser_Name.Text =“'OR 1 = 1的值;截断表YourTable; - ”

生成的查询看起来像     从UsernameInfo中选择*,其中Username =''OR 1 = 1;截断表YourTable; - '和密码='没关系'

你实际上会执行第一个语句,该语句将通过“OR 1 = 1”返回所有行,这始终为true,然后下一个语句将删除“YourTable”中的所有记录,这些记录可能是数据库的一部分。最后,'和密码部分将被完全忽略,因为它是通过 - 。

评论的

更有意义吗?