编码平台: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")
我的问题是
- 字典是实现这一点的最佳数据结构吗?
- 键的排序由通用字典改变键值索引在查询?
- 将所有键提取到一个数组中,并将相应的值提取到另一个匹配的数组中。
还有,其他更好的方法是什么?
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。文本}});