You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ASP.NET MVC写入数据库时遇「输入字符串格式不正确」错误求助

解决“Input String Was Not In Correct Format”错误(针对SQL Server money类型写入)

嘿,我来帮你搞定这个问题!你遇到的这个错误,核心原因就是最后两列的处理方式和目标数据库类型不匹配,而且你的代码还存在安全风险,咱们一起把它修正过来。

问题根源分析

  • 你的目标表中AnnualizedBaseAnnualizedTCC是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();
        }
    }
}

关键修改点说明

  1. 参数化查询:彻底避免SQL注入,同时让数据库自动处理数据类型的匹配,不用手动纠结字符串格式。
  2. money类型适配:用decimal.TryParse()转换输入值,因为SQL Server的money类型和C#的decimal完美兼容,TryParse还能避免转换失败时直接抛出异常,让你可以优雅处理错误数据。
  3. 资源管理:用using语句管理SqlConnection和SqlCommand,确保连接和命令对象自动释放,避免资源泄漏。
  4. 数据清理:提前移除输入中的货币符号($)和千分符(,),减少转换失败的概率。

内容的提问来源于stack exchange,提问作者Sartorialist

火山引擎 最新活动