将SqlParameter添加到SqlCommand的通用方法

时间:2019-04-23 17:06:50

标签: c# sql-server sql-injection sqlparameters

我们有一个旧式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 个答案:

答案 0 :(得分:2)

我写了一个快速的通用方法,可以执行您想要的操作。它使用正则表达式查找所有参数(必须以@字符作为前缀)

    // 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;
    }

您可以使用params object []来传递查询中每个参数的值,从而构建SQL命令。用法示例为:

        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);
                    }
                }
            }
        }

答案 1 :(得分:0)

@Jon写的是一个很好的解决方案,但以防万一您想要更多。我建立了一个ORM库,可以处理几乎所有可能的senario。

Nuget

CodeProject

Github

现在您可以简单地像这样执行一个SQL。

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

String[..] Date[..] and Guid[..]稍后将转换为参数。 您也可以手动添加参数,请阅读文档以了解更多信息