防止注入的C#和SQL参数
我想知道(在下面的代码中)如何确保下面传递的参数中的dataID是文本(或varchar或int)防止注入的C#和SQL参数,c#,.net,sql,data-access-layer,sqlparameter,C#,.net,Sql,Data Access Layer,Sqlparameter,我想知道(在下面的代码中)如何确保下面传递的参数中的dataID是文本(或varchar或int) public T ExecuteQuery<T>(Func<IDataReader, T> getResult, string query, params IDataParameter[] parameters) { using (SqlConnection conn = new SqlConnection(this.DefaultConnectio
public T ExecuteQuery<T>(Func<IDataReader, T> getResult, string query, params IDataParameter[] parameters)
{
using (SqlConnection conn = new SqlConnection(this.DefaultConnectionString))
{
conn.Open();
// Declare the parameter in the query string
using (SqlCommand command = new SqlCommand(query, conn))
{
foreach (var parameter in parameters)
{
command.Parameters.Add(parameter);
}
command.Prepare();
using (SqlDataReader dr = command.ExecuteReader())
{
return getResult(dr);
}
}
}
}
public string GetMySpecId(string dataId)
{
return ExecuteQuery(
dr =>
{
if (dr.Read())
{
return dr[0].ToString();
}
return string.Empty;
},
"select specId from MyTable where dataId = @dataId",
new SqlParameter("dataId", dataId));
}
在顶部的代码中,我如何将两个或多个参数传递到ExecuteQuery?代码使用的是关键字,因此您似乎应该只编写额外的转义SQL,并将参数一直附加到方法的末尾。下面是一个以代码为基础的示例
该链接提供了更全面的解释,但params
提供了更全面的解释,这样您就可以在方法签名的末尾拥有数量可变的参数(只要它们是相同的类型)。它将此params
变量中的所有最终参数放入一个数组中
return ExecuteQuery(
dr =>
{
if (dr.Read())
{
return dr[0].ToString();
}
return string.Empty;
},
"select specId from MyTable where dataId = @dataId and somethingelse = @else",
new SqlParameter("dataId", dataId),
new SqlParameter("else", elseVar);
代码使用的是关键字,因此您似乎应该只编写额外的转义SQL,并继续将参数附加到方法的末尾。下面是一个以代码为基础的示例
该链接提供了更全面的解释,但params
提供了更全面的解释,这样您就可以在方法签名的末尾拥有数量可变的参数(只要它们是相同的类型)。它将此params
变量中的所有最终参数放入一个数组中
return ExecuteQuery(
dr =>
{
if (dr.Read())
{
return dr[0].ToString();
}
return string.Empty;
},
"select specId from MyTable where dataId = @dataId and somethingelse = @else",
new SqlParameter("dataId", dataId),
new SqlParameter("else", elseVar);
ExecuteQuery
已接受多个参数。它是一个ParamArray
,这意味着它接受任意数量的参数并将它们转换为一个数组
return ExecuteQuery(
dr =>
{
if (dr.Read())
{
return dr[0].ToString();
}
return string.Empty;
},
"select specId from MyTable where dataId = @dataId and somethingelse = @else",
new SqlParameter("dataId", dataId),
new SqlParameter("else", elseVar);
例如,如果我有这样一个函数:
public int Sum(params int[] numbersToSum) { ... }
Sum(1, 2, 5, 6, 1)
我可以这样称呼它:
public int Sum(params int[] numbersToSum) { ... }
Sum(1, 2, 5, 6, 1)
在您的情况下,您可以这样称呼它:
ExecuteQuery(
dr => { //snip },
query,
new SqlParameter("dataId", dataId),
new SqlParameter("anotherParm", parm2),
new SqlParameter("anotherParm", parm3),
... );
ExecuteQuery
已接受多个参数。它是一个ParamArray
,这意味着它接受任意数量的参数并将它们转换为一个数组
return ExecuteQuery(
dr =>
{
if (dr.Read())
{
return dr[0].ToString();
}
return string.Empty;
},
"select specId from MyTable where dataId = @dataId and somethingelse = @else",
new SqlParameter("dataId", dataId),
new SqlParameter("else", elseVar);
例如,如果我有这样一个函数:
public int Sum(params int[] numbersToSum) { ... }
Sum(1, 2, 5, 6, 1)
我可以这样称呼它:
public int Sum(params int[] numbersToSum) { ... }
Sum(1, 2, 5, 6, 1)
在您的情况下,您可以这样称呼它:
ExecuteQuery(
dr => { //snip },
query,
new SqlParameter("dataId", dataId),
new SqlParameter("anotherParm", parm2),
new SqlParameter("anotherParm", parm3),
... );
如何使类型也被传递,比如SqlDBType.NVarchar?假设您使用的是
System.Data.SqlClient
中的SqlParameter
类,那么您可以在正在传递的SqlParameter
对象上设置它(属性SqlDBType
)。但是,SqlDBType
是从构造函数中给定的.NET对象推断出来的,因此您不需要指定它:如何使它也像SqlDBType.NVarchar一样传递类型?假设您在System.Data.SqlClient
中使用SqlParameter
类,这是您可以在传递的SqlParameter
对象上设置的内容(属性SqlDBType
)。但是,SqlDBType
是从构造函数中给定的.NET对象推断出来的,因此您不需要指定它:它们是什么类型的?我还想传递不同的类型,也许我应该将其更改为字典?它们是什么类型的?我还想传递不同的类型,也许我应该把它改成字典?