使用泛型字典向表插入值



编码平台:ASP。. NET 2.0 WebForms with c# with MySQL作为后端

的背景

我目前正在修复一个网站的错误。
其中一个表"registrations"有80列

插入/更新是通过简单的sql语句完成的,没有任何参数化查询。

问题

在注册时,用户可以改变许多参数,导致至少15种INSERT查询。我的问题是如何确保所有字段都插入正确的值。

因此,我创建了一个
Dictionary<string, string> fields = new Dictionary<string, string>();
fields.Add("LoginEmail", MySQL.SingleQuoteSQL(txtLoginEmail.Text));
fields.Add("Password", MySQL.SingleQuoteSQL(txtLoginPassword.Text));
fields.Add("ContactName", MySQL.SingleQuoteSQL(txtContactName.Text));
fields.Add("City", MySQL.SingleQuoteSQL(txtCity.Text));

我的想法是做一个简单的插入查询,像这样

INSERT INTO registrations("all keys as comma separated string") VALUES ("all keys as comma separated string") 

我的问题是

  1. 字典是实现这一点的最佳数据结构吗?
  2. 键的排序由通用字典改变键值索引在查询?
  3. 将所有键提取到一个数组中,并将相应的值提取到另一个匹配的数组中。

还有,其他更好的方法是什么?

p。S:我正在维护代码,并制作一个实体类,将列映射到属性并存储值,这不是一个选项。

 string list<T>(IEnumerable<T> enumerable)
 {
   List<T> list = new List<T>(enumerable);
   return string.Join(",", list.ToArray());
 } 
//...
string sql= String.Format("INSERT INTO registrations({0}) VALUES({1})",
                list(fields.Keys),
                list(fields.Values));

我认为在这种情况下字典结构是可以的,但是

按原样构建和执行字符串允许SQL注入攻击

xkcd.com/327/A Mom的漏洞

我正在使用。net 3.5,但这个想法也可以应用到。net 2.0

如果MySQL。SingleQuoteSQL比它的名字暗示更多,请告诉我

否则添加值作为参数以防止

var values = new Dictionary<string, string>() {
  {"LoginEmail", "LoginEmail"},
  {"Password", "Password"},
  {"ContactName", "ContactName"},
  {"City", "City"}
};
System.Func<string, string> key = p => String.Concat("?", p);
var statement = string.Format("INSERT INTO registrations ({0}) VALUES ({1})", 
  string.Join(",", values.Values.ToArray()),
  string.Join(",", values.Keys.Select(key).ToArray())
);
//"INSERT INTO registrations (LoginEmail,Password,ContactName,City) VALUES (?LoginEmail,?Password,?ContactName,?City)"  
foreach(var p in values) {
  command.Parameters.Add(key(p.Key), p.Value, SqlDbType.Text);
}
command.Prepare();
command.ExecuteNonQuery();
They may be other better classes for .NET mysql, apologies if so - I haven't used mysql in .NET

我知道描述说您没有使用参数化sql,但是我认为,使用参数化sql是防止sql注入的更好方法。在txtLoginEmail中输入一些SQL并提交表单对您的情况造成严重破坏并不需要花费太多精力。

<>之前私有静态字符串CreateInsertSql(字符串表)string>IDictionary<字符串;parameterMap){var>var sql = new StringBuilder("INSERT INTO ").Append(表).Append("(");For (var I = 0;我& lt;keys.Count;我+ +){sql.Append(键[我]);If (i <钥匙。计数-><钥匙。计数->之前<>之前私有静态void SqlInsert(字符串表,字典<字符串,字符串>parameterMap){使用(var connection = AcquireConnection()){connection.Open ();使用(var command = connection.CreateCommand()){命令。Connection =连接;命令。CommandText = CreateInsertSql(表,parameterMap);foreach (var pair in parameterMap)command.Parameters.Add(一对。键,pair.Value);command.ExecuteNonQuery ();}}}之前

调用类似于:

<>之前SqlInsert("registrations", new Dictionary<string,>()){{"LoginEmail", txtLoginEmail。文本},{"Password", txtLoginPassword。文本},{"ContactName", txtContactName。文本},{城市",txtCity。文本}});

相关内容

  • 没有找到相关文章

最新更新