C#中,仿效Java中,SQL参数以?替代的做法,解决IN的防注入问题

记得以前在学习Java的时候,Java的SQL中参数用?代替,今天突发奇想就拿着项目尝试着仿效这个功能。

只考虑非IN的情况下,以?挖坑替代参数。

例如:SELECT name,age FROM UserInfo WHERE name = ?

  代码如下:

    

 1      /// <summary>
2 /// 转化单数参数
3 /// </summary>
4 /// <param name="sql">需要处理的Sql</param>
5 /// <param name="paramValues">参数值数组</param>
6 /// <returns></returns>
7 public SqlParameter[] CastSingleUnknow(ref string sql, object[] paramValues)
8 {
9 //当sql存在问号参数,则根据参数创建SqlParameter并替换sql内的问号标识
10 IList<SqlParameter> parameterList = new List<SqlParameter>();
11 if(0 <= sql.IndexOf("?") && paramValues != null && 0 < paramValues.Length)
12 {
13 sql = new Regex(@"\?").Replace(sql, mark =>
14 {
15 string paramName = this.SINGLE_PARAM + this.ParamIndex;
16 if(this.ParamIndex < paramValues.Length)
17 {
18 parameterList.Add(new SqlParameter(paramName, paramValues[this.ParamIndex++]));
19 }
20 else
21 {
22 throw new Exception("参数值数量小于问号参数数量!");
23 }
24 return paramName;
25 });
26 }
27 return parameterList.ToArray();
28 }

  将传入的SQL语句中的?转换为@name的参数名,并生成对应的SqlParameter[]。

  然后如果考虑SQL中有IN的情况下,我们一般的做法是通过拼接的方式进行,然后拼接存在着"'"这个符号,对于SQL的注入还是很危险的。我们可以将多个值转换为多个参数的形式替换SQL语句,例如:SELECT name,age FROM UserInfo WHERE name IN ('小明','小王','小李')的情况下,我们可以将SQL定义为SELECT name,age FROM UserInfo WHERE name IN (@name1,@name2,@name3)的形式,然后根据传入的值,处理出相应的SqlParameter.

  代码如下:

    

 1      /// <summary>
2 /// 转化数组参数
3 /// </summary>
4 /// <param name="sql">需要处理的Sql</param>
5 /// <param name="paramValues">参数值数组</param>
6 /// <returns></returns>
7 public SqlParameter[] CastArrayUnknow<T>(ref string sql, T[] paramValues) where T : struct
8 {
9 //当sql存在问号参数,则根据参数创建SqlParameter并替换sql内的问号标识
10 IList<SqlParameter> parameterList = new List<SqlParameter>();
11 if(0 <= sql.IndexOf("?") && paramValues != null && 0 < paramValues.Length)
12 {
13 IList<string> paramNameList = new List<string>();
14 int count = paramValues.Length;
15 for(int i = 0;i < count;i++)
16 {
17 string paramName = this.ARRAY_PARAM + i;
18 paramNameList.Add(paramName);
19 parameterList.Add(new SqlParameter(paramName, paramValues[i]));
20 }
21 sql = sql.Replace("?", string.Format(0 <= sql.IndexOf("(?)") ? "{0}" : "({0})",
22 string.Join(",", paramNameList.ToArray())));
23 }
24 return parameterList.ToArray();
25 }

  

源码文件

原文地址:https://www.cnblogs.com/ahl5esoft/p/2117506.html