在C#中调试参数化查询的最佳方法

3

如何在 asp.net c# 中转义文本框中的符号(')

根据上面帖子中的问题,大多数人建议使用“参数化查询”来避免 SQL 注入。

以下是我使用 SQL 注入的代码:

public DataSet checkemp(string user)
{
    strsql = "SELECT * from employee where employeeid = @userid";
    SqlConnection con = new SqlConnection(connectionString);
    SqlDataAdapter da = new SqlDataAdapter(strsql, connectionString);
    da.SelectCommand.Parameters.Add("@userid", SqlDbType.VarChar, 50).Value = user;    
    // pretend the user name is "Micheal"
    con.Open();
    DataSet ds = new DataSet();
    da.Fill(ds);
    con.Close();
    con.Dispose();
    return ds;
}

在调试过程中,当我指向“strsql”标签时,我只能获得查询语句“SELECT * from employee where employeeid = @userid”,而不是“SELECT * from employee where employeeid = 'Micheal'”。
有什么解决办法可以解决这个问题并使其最有效?谢谢大家!

简单的回答是否定的,无法通过悬停在“strsql”上来查看命令,如:“SELECT * from employee where employeeid ='Micheal'”。 - sujith karivelil
那就意味着在调试期间,我需要手动插入参数值到查询中以替换@userid并在SQL服务器上运行? - 120196
Yogi,如何使用用户分析器查看实际的SQL语句? - 120196
woodykiddy,因为我只能得到“SELECT * from employee where employeeid = @userid”,但不能得到“Micheal”。如果它包含20个以上的参数,我需要手动逐一替换它们。 - 120196
你应该能够使用foreach循环遍历da.SelectCommand.Parameters中的所有参数。此外,您可以尝试先创建一个参数列表,然后将它们添加到List<SqlParameter> paramList中,然后循环遍历paramList并将它们添加到命令中。 - Alex W
显示剩余5条评论
2个回答

2
我会介绍一个扩展方法(虽然这不是必须的,实际逻辑更重要),如下返回解析后的查询,并仅在debug模式下调用:
public void TestMethod()
{
    string cmdStr = "<some sql command text>";
    SqlConnection con = new SqlConnection(connectionString);
    SqlCommand cmd = new SqlCommand(cmdStr, con);
    cmd.Parameters.AddWithValue("<param1>", <value1>); // add parameter in any way you want
#if DEBUG
    string parsedQuery = cmd.GetParsedQuery();
    Console.WriteLine(parsedQuery); // or whatever
#endif  
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    con.Open();
    DataSet ds = new DataSet();
    da.Fill(ds);
    con.Close();
    con.Dispose();
    return ds;
}

public static string GetParsedQuery(this SqlCommand cmd)
{
    if(cmd.CommandType == CommandType.Text)
    {
        string parsedQuery = cmd.CommandText;
        foreach(var p in cmd.Parameters)
        {
            parsedQuery = parsedQuery.Replace(p.ParameterName, Convert.ToString(p.Value));
        }

        return parsedQuery;
    }

    return null;
}

请注意,虽然我直接编写了扩展方法(为了简洁起见),但它实际上应该在一个单独的静态类中定义。

0
尝试使用MiniProfiler:
"一款ADO.NET分析器,能够对原始的ADO.NET调用进行分析"

http://miniprofiler.com/

public DataSet checkemp(string user)
{
    strsql = "SELECT * from employee where employeeid = @userid";
    SqlConnection con = GetOpenConnection(connectionString);
    SqlDataAdapter da = new SqlDataAdapter(strsql, connectionString);
    da.SelectCommand.Parameters.Add("@userid", SqlDbType.VarChar, 50).Value = user;    
    // pretend the user name is "Micheal"
    con.Open();
    DataSet ds = new DataSet();
    da.Fill(ds);
    con.Close();
    con.Dispose();
    return ds;
}

public static DbConnection GetOpenConnection(string connectionString)
{
    var cnn = new SqlConnection(connectionString);
    // wrap the connection with a profiling connection that tracks timings 
    return new StackExchange.Profiling.Data.ProfiledDbConnection(cnn, MiniProfiler.Current);
}

** 你可能需要使用ProfiledDbCommand来包装SqlCommand


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接