Windows Forms应用插入数据库报错:TextBox转IConvertible失败
问题解决:InvalidCastException 及 SQL 注入风险修复
1. 直接触发错误的原因
你写的int StartKmReading = Convert.ToInt32(txtDTStartKmReading);犯了一个低级错误:你把TextBox控件本身传给了Convert.ToInt32,而不是控件的Text属性。对比下面的EndKmReading代码是正确的(用了.Text),把这行改成:
int StartKmReading = Convert.ToInt32(txtDTStartKmReading.Text);
就能解决InvalidCastException错误。
2. 必须修复的SQL注入风险
原代码用字符串拼接生成SQL语句,这是严重的安全漏洞,攻击者可以通过输入恶意内容篡改数据库(比如删除整张表)。同时字符串拼接还会导致日期、数值类型的格式问题,必须改用参数化查询。
修改后的完整代码
private void btnAddDT_Click(object sender, EventArgs e) { try { // 读取输入值(修复了StartKmReading的.Text问题) string invoiceNo = txtDTInvoice.Text; string vehicleNo = txtDTVehicleNo.Text; string packageType = txtDTPackageType.Text; DateTime startTime = dtpStartTimeDT.Value; DateTime endTime = dtpEndtimeDT.Value; int startKmReading = Convert.ToInt32(txtDTStartKmReading.Text); int endKmReading = Convert.ToInt32(txtDTEndKmReading.Text); double baseHire = Convert.ToDouble(txtBaseHireChargeDT.Text); double waitingFee = Convert.ToDouble(txtWaitingFeeDT.Text); double extraKmCharge = Convert.ToDouble(txtExtraKmChargeDT.Text); double totalAmount = Convert.ToDouble(txtDTTotalAmountCal.Text); // 使用参数化查询,避免SQL注入和类型格式问题 string addQ = @"INSERT INTO DayTourHires (InvoiceNo, VehicleNo, PackageType, StartTime, EndTime, StartKmReading, EndKmReading, BaseHire, WaitingFee, ExtraKmCharge, TotalAmount) VALUES (@InvoiceNo, @VehicleNo, @PackageType, @StartTime, @EndTime, @StartKmReading, @EndKmReading, @BaseHire, @WaitingFee, @ExtraKmCharge, @TotalAmount)"; using (SqlCommand comm = new SqlCommand(addQ, conn)) { // 添加参数,自动处理类型转换和格式 comm.Parameters.AddWithValue("@InvoiceNo", invoiceNo); comm.Parameters.AddWithValue("@VehicleNo", vehicleNo); comm.Parameters.AddWithValue("@PackageType", packageType); comm.Parameters.AddWithValue("@StartTime", startTime); comm.Parameters.AddWithValue("@EndTime", endTime); comm.Parameters.AddWithValue("@StartKmReading", startKmReading); comm.Parameters.AddWithValue("@EndKmReading", endKmReading); comm.Parameters.AddWithValue("@BaseHire", baseHire); comm.Parameters.AddWithValue("@WaitingFee", waitingFee); comm.Parameters.AddWithValue("@ExtraKmCharge", extraKmCharge); comm.Parameters.AddWithValue("@TotalAmount", totalAmount); conn.Open(); comm.ExecuteNonQuery(); MessageBox.Show("记录插入成功"); } } catch (Exception ex) { MessageBox.Show($"错误信息:{ex.Message}"); } finally { if (conn.State == ConnectionState.Open) { conn.Close(); } } }
3. 额外建议
- 对用户输入做合法性校验:比如判断
txtDTStartKmReading.Text是否是有效的整数,避免转换失败抛出异常,可以用int.TryParse替代Convert.ToInt32。 - 使用
using语句包裹SqlCommand(如代码中所示),确保资源自动释放。
内容的提问来源于stack exchange,提问作者sajithwi
相关产品推荐
相关产品推荐

