Member 14885854 Ответов: 3

Я hv пишу простой код, но visual studio 2010 выдает мне ошибку после запуска моей программы типа - "ссылка на объект не установлена на экземпляр объекта"


Try
            Dim myConnection As OleDb.OleDbConnection
            myConnection = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + "D:\myvbsbs\NES\NES\Database1.accdb")
            Dim myCommand As OleDbCommand
            'myCommand = New OleDb
            myCommand = New OleDbCommand("SELECT Username, Password FROM Users WHERE Username=txtUserid and Password=txtPassword")
            Dim uName As New OleDbParameter("@Username", SqlDbType.VarChar)
            Dim uPassword As New OleDbParameter("@Password", SqlDbType.VarChar)
            uName.Value = txtUserid.Text
            uPassword.Value = txtPassword.Text
            myCommand.Parameters.Add(uName)
            myCommand.Parameters.Add(uPassword)
            myCommand.Connection.Open()
            Dim myReader As OleDbDataReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection)
            Dim Login As Object = 0
            If myReader.HasRows Then
                myReader.Read()
                Login = myReader(Login)
            End If
            If Login = Nothing Then
                MsgBox("Login Failes !!!!", MsgBoxStyle.Critical, "Error.")
                txtUserid.Clear()
                txtPassword.Clear()
                txtUserid.Focus()
            Else
                ProgressBar1.Visible = True
                ProgressBar1.Maximum = 5000
                ProgressBar1.Minimum = 0
                ProgressBar1.Value = 4
                ProgressBar1.Step = 1
                For i = 0 To 5000
                    ProgressBar1.PerformStep()
                Next
                FrmMain.ToolStripStatusLabel2.Text = txtUserid.Text
                Me.Hide()
                FrmMain.Show()
            End If
            myCommand.Dispose()
            myConnection.Close()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

        End Try
    End Sub


Что я уже пробовал:

я hv искал решение своей проблемы в интернете & run devenv.exe но все равно проблема не решена.

3 Ответов

Рейтинг:
15

OriginalGriff

Это одна из самых распространенных проблем, которые нам задают, и это также та, на которую мы меньше всего готовы ответить, но вы больше всего готовы ответить сами.

Позвольте мне просто объяснить, что означает ошибка: вы пытались использовать переменную, свойство или возвращаемое значение метода, но оно содержит null - что означает, что в переменной нет экземпляра класса.
Это немного похоже на карман: у вас есть карман в рубашке, который вы используете, чтобы держать ручку. Если вы сунете руку в карман и обнаружите, что там нет ручки, вы не сможете подписать свое имя на листе бумаги - и вы получите очень смешные взгляды, если попытаетесь! Пустой карман дает вам нулевое значение (здесь нет ручки!), поэтому вы не можете сделать ничего, что обычно делали бы, когда вы извлекли свою ручку. Почему он пуст? Вот в чем вопрос - может быть, вы забыли взять ручку, когда уходили из дома сегодня утром, или, возможно, вы оставили ручку в кармане вчерашней рубашки, когда снимали ее вчера вечером.

Мы не можем сказать, потому что нас там не было, и, что еще важнее, мы даже не можем видеть вашу рубашку, не говоря уже о том, что находится в кармане!

Вернемся к компьютерам, и вы каким - то образом сделали то же самое-и мы не можем увидеть ваш код, а тем более запустить его и узнать, что содержит null, когда это не должно быть.
Но вы можете - и Visual Studio поможет вам здесь. Запустите свою программу в отладчике, и когда она выйдет из строя, VS покажет вам строку, в которой она обнаружила проблему. Затем вы можете начать просматривать различные его части, чтобы увидеть, какое значение равно null, и начать просматривать свой код, чтобы узнать, почему. Поэтому поставьте точку останова в начале метода, содержащего строку ошибки, и снова запустите программу с самого начала. На этот раз VS остановится перед ошибкой и позволит вам изучить, что происходит, пройдя через код, глядя на ваши значения.

Но мы не можем этого сделать - у нас нет вашего кода, мы не знаем, как его использовать, если бы он у нас был, у нас нет ваших данных. Так что попробуйте - и посмотрите, сколько информации вы можете узнать!

И ... не делай этого так! Никогда не храните пароли в открытом виде - это серьезная угроза безопасности. Здесь есть некоторая информация о том, как это сделать: Хранение паролей: как это сделать.[^] - код на C#, но это довольно очевидно.

И помните: если у вас есть какие-либо пользователи из Европейского союза, то применяется GDPR, а это означает, что вы должны обрабатывать пароли как конфиденциальные данные и хранить их безопасным и безопасным способом. Текст-это ни то, ни другое, и штрафы могут быть ... ГМ ... выдающийся. В декабре 2018 года немецкая компания получила относительно низкий штраф в размере 20 000 евро именно за это.


Рейтинг:
0

Patrice T

Это Visual Basic, а не Studio.
Во-первых, удалите Try/Catch, чтобы программа выдала вам сообщение об ошибке со строкой ошибки. Эта информация действительно полезна.
Возможная проблема:

myCommand = New OleDbCommand("SELECT Username, Password FROM Users WHERE Username=txtUserid and Password=txtPassword") ' Here you set a query without parameter
Dim uName As New OleDbParameter("@Username", SqlDbType.VarChar) ' Here you set a parameter that is not used by query
Dim uPassword As New OleDbParameter("@Password", SqlDbType.VarChar) ' Here you set a parameter that is not used by query
uName.Value = txtUserid.Text
uPassword.Value = txtPassword.Text
myCommand.Parameters.Add(uName)
myCommand.Parameters.Add(uPassword)


Рейтинг:
0

MadMyche

Есть несколько проблем с вашим кодом

SELECT Username, Password
FROM   Users
WHERE  Username = txtUserid
AND    Password = txtPassword
1. Почему вы выбираете имя пользователя и пароль, когда вы их уже знаете?
2. этот запрос сравнивает un/pw с другими столбцами, а не с пользовательским вводом.
3. было бы рекомендовано хэшировать или шифровать пароль, это выглядит как обычный текст

Я бы изменил запрос, чтобы просто получить Count, и используйте параметры.
SELECT Count(*)
FROM   Users
WHERE  Username = @Username
AND    Password = @Password
Следующие несколько строк выглядят нормально, вы добавляете в параметры (которые не существуют в запросе, но мы добавляем их в него) и мы приступаем к казни.
1. Установите Login = 0
2. Если есть строки, установите Login, чтобы быть читателем
3. Сравните стоимость входа в ничего чтобы узнать, не удался ли вход в систему

МММ... Логин будет следующим 0 если не было найдено ни одной строки, то нет. ничего.
Как бы то ни было, нам уже нужно изменить это, чтобы отразить измененный оператор SQL (Count) в любом случае.

Поэтому в данный момент я переписываю ваш код, чтобы адаптировать его к новой логике и упростить параметры.. и я думаю, что нашел твою проблему... вы никогда не устанавливали Connection собственность компании SqlCommand
Try
   Dim myQuery as String = "SELECT Count(*) FROM Users WHERE Username=@Username and Password=@Password"

   Dim myConnection As OleDb.OleDbConnection
   myConnection = New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + "D:\myvbsbs\NES\NES\Database1.accdb")

   Dim myCommand As OleDbCommand = New OleDbCommand(myQuery, myConnection)
   myCommand.Parameters.AddWithValue("@Username", txtUserid.Text)
   myCommand.Parameters.Add("@Password", txtPassword.Text)

   myCommand.Connection.Open()

   Dim Login As Int32 = myCommand.ExecuteScalar()

   If Login = 0 Then
      MsgBox("Login Failes !!!!", MsgBoxStyle.Critical, "Error.")
      txtUserid.Clear()
      txtPassword.Clear()
      txtUserid.Focus()
   Else
      ProgressBar1.Visible = True
      ProgressBar1.Maximum = 5000
      ProgressBar1.Minimum = 0
      ProgressBar1.Value = 4
      ProgressBar1.Step = 1
      For i = 0 To 5000
         ProgressBar1.PerformStep()
      Next
      FrmMain.ToolStripStatusLabel2.Text = txtUserid.Text
      Me.Hide()
      FrmMain.Show()
   End If

   myCommand.Dispose()
   myConnection.Close()

Catch ex As Exception
   MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Примечания и рекомендации:
1. VB-это не мой родной язык, и это было сделано в блокноте. Там могут быть опечатки.
2. Многие объекты Sql имеют перегруженные методы, которые были использованы, меньше строк.
3. Как уже отмечалось, Пароли не должны быть простыми текстовыми; см. ссылку из @OriginalGriff
4. Как @Patrice T обратите внимание, что вы можете прокомментировать try...catch для тестирования