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


    昨天写了C#中仿效Java内SQL参数以?替代的方案,但是区分了单个参数和数组参数,而且只能支持其中的一种,不能2种情况都支持。

    今天突然发现,原来可以利用params object[]参数的时候可以将数组当作参数传入,当传入对象类型的IsArray为true的时候,可以区分出单个参数还是数组参数,这样就可以在任何情况下都能将参数以?的形式替代。

    由于SQL内的参数,可以是单个参数和数组参数混合的形式,因此需要属性来区分数组参数和单个参数的下标。

     1         /// <summary>
    2 /// 单参数下标
    3 /// </summary>
    4 int ParamIndex
    5 {
    6 get;
    7 set;
    8 }
    9
    10 /// <summary>
    11 /// 数组参数下标
    12 /// </summary>
    13 int ArrayIndex
    14 {
    15 get;
    16 set;
    17 }

      

    为了方便获取当前的单个参数名和数组参数名,我使用属性的Get来获取名字。

     1         /// <summary>
    2 /// 单参数名
    3 /// </summary>
    4 string SingleParam
    5 {
    6 get
    7 {
    8 return string.Format("@param_{0}", this.ParamIndex);
    9 }
    10 }
    11
    12 /// <summary>
    13 /// 数组参数名
    14 /// </summary>
    15 string ArrayParam
    16 {
    17 get
    18 {
    19 return string.Format("@array_{0}", this.ArrayIndex);
    20 }
    21 }

      

    转化的过程中,主要是对于参数替代符号?的处理,我使用正则类的Replace方法来实现。具体代码如下:

     1 /// <summary>
    2 /// 转化问号参数
    3 /// </summary>
    4 /// <param name="sql">带问号的SQL语句</param>
    5 /// <param name="paramValues">参数值数组</param>
    6 /// <returns></returns>
    7 public SqlParameter[] CastUnknowMark(ref string sql, object[] paramValues)
    8 {
    9 //如存在问号参数并且参数值数组>0,则遍历每个问号参数,如参数下标超出参数值数量范围则抛出异常,
    10 //如当前下标的参数值为数组,则以等同于参数值数组数量的参数替换问号参数,否则替换为单个参数
    11 IList<SqlParameter> parameterList = new List<SqlParameter>();
    12 if(0 <= sql.IndexOf("?") && paramValues != null && 0 < paramValues.Length)
    13 {
    14 sql = new Regex(@"\?").Replace(sql, mark =>
    15 {
    16 string paramName = this.SingleParam;
    17 if(this.ParamIndex < paramValues.Length)
    18 {
    19 object paramValue = paramValues[this.ParamIndex];
    20 if(paramValue.GetType().IsArray)
    21 {
    22 IList values = paramValue as IList;
    23 IList<string> paramNameList = new List<string>();
    24 foreach(object obj in values)
    25 {
    26 this.ArrayIndex++;
    27 paramNameList.Add(this.ArrayParam);
    28 parameterList.Add(new SqlParameter(this.ArrayParam, obj));
    29 }
    30 paramName = string.Join(",", paramNameList.ToArray());
    31 }
    32 else
    33 {
    34 parameterList.Add(new SqlParameter(this.SingleParam, paramValue));
    35 }
    36 }
    37 else
    38 {
    39 throw new Exception("参数值数量小于问号参数数量!");
    40 }
    41 this.ParamIndex++;
    42 return paramName;
    43 });
    44 }
    45 return parameterList.ToArray();
    46 }

      

    个人觉得,有些想法应该尝试一下,虽然一开始写的不好,但是随着多次实践与思考,肯定能将代码写的更好,写的不好之处,请多多见谅。

  • 相关阅读:
    一道简单正则面试题
    给公司搭建Nuget服务
    [转]const使用详解 D
    MFC学习记录提取16进制表示码(位操作) D
    SQL Server中更新视图, 可能出现的错误及处理
    linux设置私钥登陆
    Notebook里怎样使用argparse
    本地MAC上传文件到服务器
    Springboot @Value注解 注入Integer类型
    C# 自定义委托与事件应用
  • 原文地址:https://www.cnblogs.com/ahl5esoft/p/2118131.html
Copyright © 2020-2023  润新知