具有值到字符串的SqlCommand CommandText

时间:2018-01-30 11:01:44

标签: c# sql sql-server

目前我的代码很容易受到SQL注入的攻击,因为我只是测试它。

我用来从dbo.Account

中检索记录的方式
var condition = String.Format("[Username] = '{0}' AND [Password] = '{1}' AND Active = 1", username, password);

var account = new Data.Account().Select(condition, string.Empty, 0, 0);

public List<Model.Account> Select(string condition, string orderBy, int limit = 0, int offset = 0)
{
    var list = new List<Model.Account>();
    var query = "SELECT " + TABLE_COLUMN + " FROM [DBO].[ACCOUNT]";

    if (condition != string.Empty) 
        query += " WHERE " + condition;

    if (orderBy != string.Empty || limit > 0) 
        query += " ORDER BY " (orderBy == string.Empty ? "ID DESC" : orderBy);

    if (limit > 0) 
        query += " OFFSET " + offset + " ROWS FETCH NEXT " + limit + " ROWS ONLY";

    using (var db = new SqlManager())
    {
        using (var reader = db.ExecuteReader(query))
        {
            while (reader.Read())
            {
                var item = BindData(reader);
                list.Add(item);
            }
        }
    }
}

现在我正在尝试使用SqlParameter创建一个字符串,如下所示:

SqlCommand condition = new SqlCommand("[Username] = @Username AND [Password] = @Password");
condition.Parameters.AddWithValue("@Username", username);
condition.Parameters.AddWithValue("@Password", password);

var account = GetAccountByCondition(condition.CommandText);

如何获得SqlCommand字符串以及包含的用户名和密码值?

我这样做是因为我的数据访问层是通过程序生成的。条件的S​​tring.Format确实是错误的。

我正在使用的SqlManager课程供您参考:

public class SqlManager : IDisposable
{
    private SqlConnection _connection;

    public SqlConnection Connection
    {
        get { return _connection; }
    }

    private SqlCommand _command;

    public SqlCommand Command
    {
        get { return _command; }
    }

    private SqlTransaction _transaction;

    public SqlTransaction Transaction
    {
        get { return _transaction; }
    }

    private List<SqlParameter> _parameters = new List<SqlParameter>();

    public List<SqlParameter> Parameters
    {
        get { return _parameters; }
        set { _parameters = value; }
    }

    public SqlManager()
    {
        var constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
        _connection = new SqlConnection(constr);
        _command = new SqlCommand();
        _connection.Open();
    }

    public int ExecuteNonQuery(string commandText)
    {
        return ExecuteNonQuery(commandText, CommandType.Text);
    }

    public int ExecuteNonQuery(string commandText, CommandType commandType)
    {
        _command.Connection = _connection;
        _command.Transaction = _transaction;
        _command.CommandType = commandType;
        _command.CommandText = commandText;
        _command.Parameters.Clear();
        _command.Parameters.AddRange(_parameters.ToArray());

        return _command.ExecuteNonQuery();
    }

    public object ExecuteScalar(string commandText)
    {
        return ExecuteScalar(commandText, CommandType.Text);
    }

    public object ExecuteScalar(string commandText, CommandType commandType)
    {
        _command.Connection = _connection;
        _command.Transaction = _transaction;
        _command.CommandType = commandType;
        _command.CommandText = commandText;
        _command.Parameters.Clear();
        _command.Parameters.AddRange(_parameters.ToArray());

        return _command.ExecuteScalar();
    }

    public IDataReader ExecuteReader(string commandText)
    {
        return ExecuteReader(commandText, CommandType.Text);
    }

    public IDataReader ExecuteReader(string commandText, CommandType commandType)
    {
        _command.Connection = _connection;
        _command.CommandType = commandType;
        _command.CommandText = commandText;
        _command.Parameters.Clear();
        _command.Parameters.AddRange(_parameters.ToArray());

        return _command.ExecuteReader();
    }

    public XmlReader ExecuteXml(string commandText)
    {
        return ExecuteXml(commandText, CommandType.Text);
    }

    public XmlReader ExecuteXml(string commandText, CommandType commandType)
    {
        _command.Connection = _connection;
        _command.CommandType = commandType;
        _command.CommandText = commandText;
        _command.Parameters.Clear();
        _command.Parameters.AddRange(_parameters.ToArray());

        return _command.ExecuteXmlReader();
    }

    public DataTable ExecuteDataTable(string commandText)
    {
        return ExecuteDataTable(commandText, CommandType.Text);
    }

    public DataTable ExecuteDataTable(string commandText, CommandType commandType)
    {
        _command.Connection = _connection;
        _command.CommandType = commandType;
        _command.CommandText = commandText;
        _command.Parameters.Clear();
        _command.Parameters.AddRange(_parameters.ToArray());

        var dt = new DataTable();
        dt.Load(_command.ExecuteReader());

        return dt;
    }

    public void AddParameter(string paraName, object objectValue)
    {
        AddParameter(paraName, objectValue, ParameterDirection.Input);
    }

    public void AddParameter(string paraName, object objectValue, ParameterDirection direction)
    {
        var para = new SqlParameter();
        para.ParameterName = paraName;
        para.Direction = direction;
        para.Value = objectValue;
        _parameters.Add(para);
    }

    public void BeginTransaction()
    {
        _transaction = _connection.BeginTransaction();
    }

    public void Commit()
    {
        if (_transaction != null)
        {
            _transaction.Commit();
        }
    }

    public void Rollback()
    {
        if (_transaction != null)
        {
            _transaction.Rollback();
        }
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);

        if (_connection.State == ConnectionState.Open)
        {
            _connection.Close();
        }

        _connection = null;
        _command = null;
        _transaction = null;
    }
}

1 个答案:

答案 0 :(得分:1)

您可以构建SELECT查询并将其分配给SqlCommand对象

Dim cmd As SqlCommand

cmd = New SqlCommand("SELECT * FROM [DBO].[ACCOUNT] WHERE [Username] = @username AND [Password] = @pwd AND Active = 1")
cmd.Parameters.Add(New SqlParameter("@username", txtName.Text))
cmd.Parameters.Add(New SqlParameter("@pwd", txtId.Text))

然后使用Parameters.Add方法将参数名称和值传递给prevent SQL injection,因为我也尝试在参考文档中解释。

由于您的SQL查询比上面的代码更复杂,您可以使用带有参数占位符的字符串查询变量动态构建SQL命令,然后最终将其分配给SqlCommand对象