Общий способ добавления SqlParameter к SqlCommand - PullRequest
1 голос
/ 23 апреля 2019

У нас есть старое приложение на C #, где у нас есть много встроенных SQL-запросов, которые выполняются к входным данным, которые были переданы пользователем.Итак, очевидно, что SQL-инъекция вошла в картину.Сейчас мы хотим это исправить, но дело в том, что мы хотим придерживаться минималистического подхода.Не трогая много кода.Таким образом, ORM и хранимые процедуры являются для нас чем-то вроде уравнения.

Мы должны обновить каждый встроенный оператор, чтобы использовать подход параметризации SQL.Однако, то, что я ищу, может быть, если есть общий способ сделать это.Например, отправить запрос методу и динамически сгенерировать массив SqlParameter.

Под запросом я подразумеваю буквально запрос всякий раз, когда могу, без использования обычного @

Select * 
From table 
Where id = 1 and name = 'Sean'  and            
location like  '%cali'

.

List<Sqlparameters> params = new 
List<Sqlparameters>() 

var query = Select * from table where id = @v1 and name =@v2 and location like @v3

params.Add("v1", 1)
params.Add("v2",  'Sean')
params.Add("v3","%cali") 

Обновление

Теперь у меня есть метод, который делает это для меня.Это займет текст SQL, как это

var sql = "select * from merchants where merchantID={" + Request["merchantid"] +"}"

Метод

Public command Method(string query) 
{
var cmd =new Command();
cmd.text="";
cmd.params=new List<SqlParameter>() ;


// code to trasform the query. Identify values based on the special char '{'. Dynamically adds placeholder variables and values into an array

cmd.text="select * from merchants where merchantID=@variable1

//Loops through variables and adds values
// to parameters 

cmd.parameters.Add(new SqlParameter("variable1",  value1);

return cmd;

} 

Ответы [ 2 ]

2 голосов
/ 23 апреля 2019

Я написал быстрый общий метод, который будет делать то, что вы хотите. Он использует регулярные выражения для поиска всех параметров (они должны начинаться с префикса @)

    // This will build a SqlCommand from query text, and build SqlParameters
    // foreach "@Param" in the query e.g. WHERE Name = @Name and Date = @Date
    private SqlCommand GenerateSqlCommand(string queryText, params object[] paramValues)
    {
        // Build SqlCommand
        var sqlCommand = new SqlCommand(queryText);
        sqlCommand.CommandType = System.Data.CommandType.Text;

        // Find all instances of @Param sql parameter names in the query
        var matches = Regex.Matches(queryText, @"[@#]\w+");
        for (int i = 0; i < matches.Count; i ++)
        {
            // Add this parameter to the command with the value from the paramValues
            // Parameters passed into the method must be in order 
            // E.g. if the Query is "SELECT * FROM TABLE where Name = @Name and Date = @Date
            // then paramValues must be { 'My Name', '04-24-2019' }
            sqlCommand.Parameters.AddWithValue(matches[i].Value, paramValues[i]);
        }

        // Return command
        return sqlCommand;
    }

Вы можете использовать это для построения вашей SQL-команды, используя объект params [], чтобы передать значения для каждого параметра в запросе. Пример использования:

        using (var conn = GetSqlConnection())
        {
            var param1 = "This is a parameter";
            var param2 = "04/23/2019";
            var param3 = 2;

            using (var comm = GenerateSqlCommand("SELECT * FROM Users WHERE Username = @Username and Date = @Date and Id = @Id", param1, param2, param3))
                {
                comm.Connection = conn;
                using (var reader = comm.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        // TODO: handle the results
                        reader.GetString(0);
                        reader.GetInt32(1);
                    }
                }
            }
        }
0 голосов
/ 23 апреля 2019

То, что написал @Jon, является хорошим решением, но на всякий случай, если вы хотите большего. Я создаю библиотеку ORM, которая может обрабатывать почти все возможные сенарио.

NuGet

CodeProject

Github

Теперь вы можете вместо этого просто выполнить sql.

var cmd = rep.GetSqlCommand("SELECT * FROM Users WHERE UserName = String[admin]");

String[..] Date[..] and Guid[..] будет преобразован в параметр позже. Вы также можете добавить параметр вручную, прочитайте документацию, чтобы понять больше

...