ASP.NET MVC写入数据库时遇「输入字符串格式不正确」错误求助
解决“Input String Was Not In Correct Format”错误(针对SQL Server money类型写入)
嘿,我来帮你搞定这个问题!你遇到的这个错误,核心原因就是最后两列的处理方式和目标数据库类型不匹配,而且你的代码还存在安全风险,咱们一起把它修正过来。
问题根源分析
- 你的目标表中
AnnualizedBase和AnnualizedTCC是SQL Server的money类型,但你用了Convert.ToInt32()去转换输入值——如果输入是带小数的金额,或者包含货币符号、千分符这类格式字符,转换直接就会失败,抛出你看到的格式错误。 - 另外,你直接拼接SQL字符串的做法存在严重的SQL注入风险,这是生产环境绝对不能用的写法,必须换成参数化查询。
修正后的代码
下面是优化后的代码,既解决了类型转换问题,又消除了安全隐患:
// 先获取连接字符串,避免重复读取配置 string connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; // 使用using语句自动管理连接资源,避免连接泄漏 using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); // 定义带参数的SQL模板,放在循环外面复用 string query = @"INSERT INTO Upload(Email, TimeStamp, EmployeeId, Name, Title, Department, Race, Gender, AnnualizedBase, AnnualizedTCC) VALUES (@Email, @TimeStamp, @EmployeeId, @Name, @Title, @Department, @Race, @Gender, @AnnualizedBase, @AnnualizedTCC)"; for (int i = 0; i < result.Tables[0].Rows.Count; i++) { using (SqlCommand cmd = new SqlCommand(query, con)) { // 逐个添加参数,让数据库自动处理类型映射 cmd.Parameters.AddWithValue("@Email", System.Web.HttpContext.Current.User.Identity.GetUserId()); cmd.Parameters.AddWithValue("@TimeStamp", DateTime.Now); cmd.Parameters.AddWithValue("@EmployeeId", result.Tables[0].Rows[i][0].ToString()); cmd.Parameters.AddWithValue("@Name", result.Tables[0].Rows[i][1].ToString()); cmd.Parameters.AddWithValue("@Title", result.Tables[0].Rows[i][2].ToString()); cmd.Parameters.AddWithValue("@Department", result.Tables[0].Rows[i][3].ToString()); cmd.Parameters.AddWithValue("@Race", result.Tables[0].Rows[i][4].ToString()); cmd.Parameters.AddWithValue("@Gender", result.Tables[0].Rows[i][5].ToString()); // 处理money类型列:用decimal.TryParse做安全转换(money和decimal是最佳兼容类型) string baseValue = result.Tables[0].Rows[i][6].ToString().Replace("$", "").Replace(",", "").Trim(); if (decimal.TryParse(baseValue, out decimal annualizedBase)) { cmd.Parameters.AddWithValue("@AnnualizedBase", annualizedBase); } else { // 转换失败时的兜底处理,比如赋值0或者记录错误日志 cmd.Parameters.AddWithValue("@AnnualizedBase", 0m); } string tccValue = result.Tables[0].Rows[i][7].ToString().Replace("$", "").Replace(",", "").Trim(); if (decimal.TryParse(tccValue, out decimal annualizedTCC)) { cmd.Parameters.AddWithValue("@AnnualizedTCC", annualizedTCC); } else { cmd.Parameters.AddWithValue("@AnnualizedTCC", 0m); } // 执行插入 cmd.ExecuteNonQuery(); } } }
关键修改点说明
- 参数化查询:彻底避免SQL注入,同时让数据库自动处理数据类型的匹配,不用手动纠结字符串格式。
- money类型适配:用
decimal.TryParse()转换输入值,因为SQL Server的money类型和C#的decimal完美兼容,TryParse还能避免转换失败时直接抛出异常,让你可以优雅处理错误数据。 - 资源管理:用
using语句管理SqlConnection和SqlCommand,确保连接和命令对象自动释放,避免资源泄漏。 - 数据清理:提前移除输入中的货币符号($)和千分符(,),减少转换失败的概率。
内容的提问来源于stack exchange,提问作者Sartorialist




