我有一个 asp.net 应用程序,它使用 post 表单保存一些用户数据。为此,我在下面列出了一个简单的查询。
"UPDATE myTable SET LastUpdatedOn='"
+ DateTime.UtcNow + "', Completed='1'
WHERE ID='" + requestid + "'"
这有时会失败。但我认为这没有问题。所以请让我知道为什么会这样。
您应该熟悉参数化查询,并开始使用它们来保护您的系统免受SQL 注入攻击。
using (var cmd = conn.CreateCommand()) {
cmd.CommandText =
"UPDATE myTable SET LastUpdatedOn=@Time, Completed='1' WHERE ID=@Id";
cmd.Parameters.AddWithValue("@Time", DateTime.UtcNow);
cmd.Parameters.AddWithValue("@Id", requestid);
var count = cmd.ExecuteNonQuery();
if (count != 1) {
Console.Error.WriteLine(
"Warning: Cannot update myTable for ID {0}", requestid
);
}
}
作为一个额外的好处,这种方法消除了所有可能的数据格式问题,并通过让 SQL Server 缓存查询计划来加快查询速度。但主要的好处是阻止世界上的“Bobby Tables”企图未经授权访问您的系统。
DateTime.UtcNow
考虑getdate()
在您使用的任何数据库中使用 if Sql Sevrer 或类似函数
"UPDATE myTable SET LastUpdatedOn= getdate(), Completed='1' WHERE ID='" + requestid + "'"
DateTime.UtcNow
不太可能解析为查询的日期时间。尝试:
DateTime.UtcNow.ToString('yyyy-MM-dd hh:mm:ss')
(另外,我可能搞砸了我的“m”,所以仔细检查一下)
我不完全确定为什么这会中断。我们需要查看表的模式才能更好地了解可能出现的问题。另一方面,我建议您使用参数化查询,而不是简单地连接您的查询。根据输入的来源,您当前的查询可能容易受到 SQL 注入的攻击。尝试将您的代码更改为类似的内容,看看它是否可以缓解错误(这也将缓解 SQL 注入风险):
SqlCommand cmd = new SqlCommand("UPDATE myTable SET LastUpdatedOn = @LastUpdatedOn, Completed = @Completed WHERE ID = @RequestId", sqlConnectionObject);
cmd.Parameters.AddWithValue("@LastUpdatedOn", DateTime.UtcNow);
cmd.Parameters.AddWithValue("@Completed", 1);
cmd.Parameters.AddWithValue("@RequestId", requestid);
cmd.ExecuteNonQuery();