ASP.NET,C#如何将StringQuery传递给自定义SQL命令

时间:2016-02-24 22:08:24

标签: c# sql asp.net ado.net

我有一个小问题,我有一个ASP.NET Webforms应用程序。我发送的url?id=X X是我的数据库索引或ID。

我有一个C#类文件来运行我的SQL连接和查询。这是代码:

public DataTable ViewProduct(string id)
{
    try
    {
        string cmdStr = "SELECT * Products WHERE Idx_ProductId = " + id;

        DBOps dbops = new DBOps();
        DataTable vpTbl = dbops.RetrieveTable(cmdStr, ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString);
        return vpTbl;
    }
    catch (Exception e)
    {
        return null;
    }
}

因此,您可以在string cmdStr = "SQL Query" + variable;

中看到我的问题

我正在通过网址传递我的索引或ID,然后请求它并将其转换为字符串,然后使用ViewProduct(productId)

我不知道是什么语法或如何将id添加到我的C#字符串sql查询中。我试过了:

string cmdStr = "SELECT * Products WHERE Idx_ProductId = @0" + id;
string cmdStr = "SELECT * Products WHERE Idx_ProductId = {0}" + id;

我现在也无济于事。

2 个答案:

答案 0 :(得分:4)

我很确定这会与C#中有关参数化查询的一些规范问题重复,但显然没有一个(参见this)!

您应该对查询进行参数化 - 如果您不这样做,则会冒着将恶意代码注入查询的风险。例如,如果您当前的代码可以针对数据库运行,那么使代码执行如下操作将是微不足道的:

// string id = "1 OR 1=1"
"SELECT * Products WHERE Idx_ProductId = 1 OR 1=1" // will return all product rows
// string id = "NULL; SELECT * FROM UserPasswords" - return contents of another table
// string id = "NULL; DROP TABLE Products" - uh oh
// etc....

ADO.NET提供了非常简单的功能来参数化您的查询,而您的DBOps类肯定没有使用它(您正在传递一个构建的命令字符串)。相反,你应该做这样的事情:

public DataTable ViewProduct(string id)
{
    try
    {
        string connStr = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
        using (SqlConnection conn = new SqlConnection(connStr))
        {
            conn.Open();
            using (SqlCommand cmd = conn.CreateCommand())
            {
                // @id is very important here!
                // this should really be refactored - SELECT * is a bad idea
                // someone might add or remove a column you expect, or change the order of columns at some point
                cmd.CommandText = "SELECT * Products WHERE Idx_ProductId = @id";
                // this will properly escape/prevent malicious versions of id
                // use the correct type - if it's int, SqlDbType.Int, etc.
                cmd.Parameters.Add("@id", SqlDbType.Varchar).Value = id;
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    DataTable vpTbl = new DataTable();
                    vpTbl.Load(reader);
                    return vpTbl;
                }
            }
        }
    }
    catch (Exception e)
    {
        // do some meaningful logging, possibly "throw;" exception - don't just return null!
        // callers won't know why null got returned - because there are no rows? because the connection couldn't be made to the database? because of something else?
    }
}

现在,如果有人试图传递" NULL; SELECT * FROM SensitiveData",它将被正确地参数化。 ADO.NET/Sql Server将其转换为:

DECLARE @id VARCHAR(100) = 'NULL; SELECT * FROM SensitiveData';
SELECT * FROM PRoducts WHERE Idx_ProductId = @id;

将不会返回任何结果(除非您的Idx_ProductId实际上是该字符串),而不是返回第二个SELECT的结果。

一些额外的阅读:

答案 1 :(得分:0)

Products.Idx_ProductId是什么类型的?

可能是字符串,而不是你需要使用引号:“... ='”+ id.Trim()+“'”;