C# SQL Query - оператор If не работает

Я пытаюсь изучить C#, и я пишу систему, в которой вам нужно войти в систему, я храню данные в базе данных и загружаю ее с кодом. Данные загружаются без ошибок, я могу Console.WriteLine, и все в порядке, но когда я запускаю сравнение, оно всегда терпит неудачу. Вот соответствующий код.

Обновлено: я пробовал без использования $ в сравнении строк, но он все еще не работает

    private void login_button_Click(object sender, EventArgs e)
    {
        // App.config stores configuration data
        // System.Data.SqlClient provides classes
        // for accessing a SQL Server DB

        // connectionString defines the DB name, and
        // other parameters for connecting to the DB

        // Configurationmanager provides access to
        // config data in App.config
        string provider = ConfigurationManager.AppSettings["provider"];

        string connectionString = ConfigurationManager.AppSettings["connectionString"];

        // DbProviderFactories generates an 
        // instance of a DbProviderFactory
        DbProviderFactory factory = DbProviderFactories.GetFactory(provider);

        // The DBConnection represents the DB connection
        using (DbConnection connection =
            factory.CreateConnection())
        {
            // Check if a connection was made
            if (connection == null)
            {
                Console.WriteLine("Connection Error");
                Console.ReadLine();
                return;
            }

            // The DB data needed to open the correct DB
            connection.ConnectionString = connectionString;

            // Open the DB connection
            connection.Open();

            // Allows you to pass queries to the DB
            DbCommand command = factory.CreateCommand();

            if (command == null)
            {
                return;
            }

            // Set the DB connection for commands
            command.Connection = connection;

            // The query you want to issue
            command.CommandText = $"SELECT * FROM Users WHERE Username = '{username_input.Text}'";

            // DbDataReader reads the row results
            // from the query
            using (DbDataReader dataReader = command.ExecuteReader())
            {
                dataReader.Read();
                //while(dataReader.Read())
                //{
                    if ($"{password_input.Text}" ==$"{dataReader["Password"]}")
                    {
                        MessageBox.Show("Logged in");
                    }
                    else
                    {
                        MessageBox.Show("Invalid Credentials!");
                    }
                //}
            }
        }
    }
}

Ваш скрипт подвержен риску атак с использованием SQL-инъекций.

gunr2171 29.11.2018 18:50

@ gunr2171 дело не в этом, я изучаю C# и то, как взаимодействовать с базами данных, а не как защищать приложения.

Throupy 29.11.2018 18:51

посмотрели ли вы в отладчике, что находится в username_input.Text и dataReader ["Password"]

pm100 29.11.2018 18:51

@Throupy, возможно, ваш вопрос не в этом, но, тем не менее, это твердый совет, которому нужно следовать. Развивайте хорошие привычки, а не плохие. Прямо сейчас у вас развивается дурная привычка писать непараметризованные запросы. Научитесь делать это правильно с первого раза.

user47589 29.11.2018 18:52
I am learning C# and how to interact with databases <= тогда вы должны параметризовать свои запросы. Это минимальное усилие.
Igor 29.11.2018 18:52

Хотя мы не можем видеть вашу фактическую модель данных, похоже, вы сравниваете значение текстового поля username со значением password, поступающим из БД ...

Steve Danner 29.11.2018 18:52

а почему не просто старый добрый if (username_input.TExt == dataReader["Password")? Почему сложная строка интерполируется

pm100 29.11.2018 18:52

@SteveDanner Это должен быть password_input, извините, я исправил его сейчас.

Throupy 29.11.2018 18:53

@ Игорь Это должен быть password_input, я его поменял. И они точно такие же, когда я смотрю в отладчик

Throupy 29.11.2018 18:54

@ pm100 Я тоже это сделал, посмотрим, будет ли разница, с OR без них не работало

Throupy 29.11.2018 18:54

Возможно, при сравнении попробуйте использовать Trim() на обеих струнах. Это сожгло меня раньше

Steve Danner 29.11.2018 18:55

Зачем ты делаешь $"{password_input.Text}"? В этом нет необходимости. password_input.Text уже будет строкой, нет необходимости использовать интерполяцию строк.

mason 29.11.2018 18:55

@ gunr2171, тем не менее, спасибо, что рассказали мне, я разберусь с этим.

Throupy 29.11.2018 18:55

@mason да, я пробовал, не повезло :(

Throupy 29.11.2018 18:56

ВЫ ОСТАНОВИЛИСЬ НА СТРОКЕ СРАВНЕНИЯ С ОТЛАДЧИКОМ И ПОСМОТРЕЛИ СРАВНИВАЕМЫЕ ЗНАЧЕНИЯ - проблема будет сразу очевидна - извините за крик, но мне нужно было привлечь ваше внимание

pm100 29.11.2018 18:56

@Throupy Что значит "не повезло"? Не нужно везения. Я не говорю вам, как решить вашу проблему, я говорю вам, как очистить ваш синтаксис.

mason 29.11.2018 18:57

@Throupy, что касается предложения Trim, если ваше поле пароля представляет собой CHAR в базе данных, а не VARCHAR, это БУДЕТ проблемой.

Steve Danner 29.11.2018 18:58

@ pm100 они точно такие же, когда я смотрю в отладчик. Если я делаю это правильно, то это так.

Throupy 29.11.2018 18:58

@SteveDanner да, это в nchar в базе данных, сейчас я заменю его на varchar

Throupy 29.11.2018 18:59

@Throupy Они не могут быть одинаковыми. Если бы они были, вы бы здесь не задавали этот вопрос. Вы абсолютно уверены, что ни один из них не начинается и не заканчивается пробелом, и что ни один из них не содержит непечатаемых символов Юникода?

user47589 29.11.2018 19:00

Весь этот код ошибочен; это не то, как вводить пароли.

Dour High Arch 29.11.2018 19:04

они явно не то же самое. Наиболее вероятные проблемы (как говорили другие) заключаются в том, что у вас есть конечный пробел в одном из значений, поэтому предложение, которое вы делаете для них, Trim

pm100 29.11.2018 19:42

Возможный дубликат Каковы хорошие способы предотвратить SQL-инъекцию?

mjwills 29.11.2018 21:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
23
152
2

Ответы 2

Начните с правильного пути с изучения C# с некоторыми советами, которые я уже видел в комментариях, а также с некоторыми дополнительными советами ниже:

Параметризуйте свои запросы как минимум Нижеприведенный способ открыт для SQL-инъекции

 command.CommandText = $"SELECT * FROM Users WHERE Username = '{username_input.Text}'";

Вместо этого это должно быть записано как: (Имейте в виду, что есть более короткие способы написать это, но я говорю прямо, так как вы учитесь)

var usernameParam = new SqlParameter("username", SqlDbType.VarChar);
usernameParam.Value = username_input.Text;

command.Parameters.Add(usernameParam);
command.CommandText = "SELECT * FROM Users WHERE Username = @username";

Во-вторых, отладка - ваш друг. Вам нужно добавить точку останова в строке, которая не работает, и использовать встроенные в Visual Studio Watchers для просмотра ваших переменных. Это даст вам больше информации, чем console.writeline (), и решит больше проблем, чем вы можете себе представить.

Большое спасибо за ваше время, что касается отладки Visual Studio? Как мне это сделать, я никогда раньше не использовал vs

Throupy 29.11.2018 19:05

@Throupy Это не то, о чем стоит просто спрашивать людей. Вместо этого вам следует изучить его. У Microsoft есть много документации по этому поводу, и на YouTube и Channel 9 есть много видео, демонстрирующих использование отладчика Visual Studio.

mason 29.11.2018 19:07

Это та IDE, которую вы используете? Как новому программисту, вам необходимо провести небольшое исследование, простой поиск в Google «Отладка в Visual Studio» приводит к замечательному ресурсу здесь docs.microsoft.com/en-us/visualstudio/debugger/…

Scornwell 29.11.2018 19:08
  1. Всегда используйте в запросах параметры вместо конкатенации строк. Он защищает от внедрения sql (не применимо к MS Access) и гарантирует, что у вас никогда не будет проблем со строками, содержащими escape-символы.
  2. Я заметил, что у вас, вероятно, есть пароль в виде простого текста, никогда не храните пароли в виде обычного текста!
  3. В этом конкретном случае использование ExecuteScalar упрощает логику (IMO). Если вы хотите вернуть данные и прочитать их с помощью устройства чтения данных, не используйте * для возврата. Вместо этого укажите имена столбцов. Это защитит ваш код от изменений схемы, таких как добавление столбцов или изменение порядка столбцов.
command.CommandText = "SELECT [Password] FROM [Users] WHERE [Username] = @userName";

// using DbCommand adds a lot more code than if you were to reference a non abstract implementation when adding parameters
var param = command.CreateParameter();
param.ParameterName = "@userName";
param.Value = username_input.Text;
param.DbType = DbType.String;
param.Size = 100;
command.Parameters.Add(param);

// compared with SqlDbCommand which would be 1 line
// command.Parameters.Add("@userName", SqlDbType.VarChar, 100).Value = username_input.Text;

var result = command.ExecuteScalar()?.ToString();
if (string.Equals(password_input.Text, result, StringComparison.Ordinal))
    MessageBox.Show("Logged in");
else
    MessageBox.Show("Invalid Credentials!");

Другие вопросы по теме