ASP.NET+C#保存课程数据报错:nvarchar值'400,000'转int失败
问题描述
我正在使用ASP.NET与C#开发业务应用,在学生管理系统的课程信息录入页面输入数据后点击保存按钮时,程序抛出如下用户未处理异常:
Exception User-unhandled
System.Data.SqlException: 'Conversion failed when converting the nvarchar value '400,000' to datatype int.'
报错触发场景:在课程费用输入框填入带千分位分隔符的数值400,000后提交,触发上述类型转换异常。
相关代码
前端页面 CoursePage.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/SMS.Master" AutoEventWireup="true" CodeBehind="CoursePage.aspx.cs" Inherits="Student_Management_System.CoursePage" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server"> <h1>Course Page</h1> <div style ="background-color:aqua; width: 292px; margin-left: 0px;"> <table> <tr> <td>Course Name:</td> <td> <asp:TextBox ID="TxtCourseName" runat="server"></asp:TextBox></td> </tr> <tr> <td>Course Fee:</td> <td> <asp:TextBox ID="TxtCourseFee" runat="server"></asp:TextBox></td> </tr> <tr> <td>Course Duration:</td> <td> <asp:DropDownList ID="DropDownList1" runat="server"> <asp:ListItem Text="-- SELECT --" Value="select" Selected="True"></asp:ListItem> <asp:ListItem Text="3 Months" Value="3 Months"></asp:ListItem> <asp:ListItem Text="6 Months" Value="6 Months"></asp:ListItem> <asp:ListItem Text="9 Months" Value="9 Months"></asp:ListItem> <asp:ListItem Text="1 Year" Value="1 Year"></asp:ListItem> <asp:ListItem Text="2 Years" Value="2 Years"></asp:ListItem> </asp:DropDownList></td> </tr> <tr> <td> </td> <td> <asp:Button ID="ButCourse" runat="server" Text="Save" OnClick="ButCourse_Click" /></td> <td> </tr> </table> </div> </asp:Content>
后端逻辑代码 CoursePage.aspx.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; using System.Data.SqlClient; using System.Configuration; namespace Student_Management_System { public partial class CoursePage : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void ButCourse_Click(object sender, EventArgs e) { string mainconn = ConfigurationManager.ConnectionStrings["Myconnection"].ConnectionString; SqlConnection sqlconn = new SqlConnection(mainconn); string sqlquery = "Insert into [dbo].[Course] (CourseName, CourseFee, CourseDuration) values (@CourseName, @CourseFee, @CourseDuration)"; SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn); sqlconn.Open(); sqlcomm.Parameters.AddWithValue("@CourseName", TxtCourseName.Text); sqlcomm.Parameters.AddWithValue("@CourseFee", TxtCourseFee.Text); sqlcomm.Parameters.AddWithValue("@CourseDuration", DropDownList1.Text); sqlcomm.ExecuteNonQuery(); Response.Write("<script>alert('Course Added Successfully.!!');</script>"); TxtCourseName.Text = ""; TxtCourseFee.Text = ""; sqlconn.Close(); } } }
问题根因
报错核心是类型不匹配:
- 数据库中
CourseFee字段为int类型,仅支持纯数字格式的整数值 - 代码直接将输入框中带千分位逗号的字符串
"400,000"传入SQL参数,SQL Server尝试将带特殊符号的字符串转换为int时失败,抛出转换异常 - 代码使用
AddWithValue传参时未显式指定参数类型,系统会默认按字符串类型处理传入值,进一步触发隐式转换问题 - 原有逻辑未做输入校验,也没有数据库连接异常释放机制,一旦SQL执行报错,数据库连接会泄漏。
修复方案
按以下逻辑修改后端代码即可解决问题:
- 提交前先做基础输入校验,拦截空值、未选择下拉项、非法费用格式的请求
- 处理课程费用输入值,移除千分位逗号后解析为整数类型,再传入SQL参数
- 显式指定SQL参数的对应类型,避免自动类型推断带来的隐式转换问题
- 用
using块包裹数据库连接对象,异常场景下也能自动释放连接,不需要手动调用Close方法
修改后的ButCourse_Click方法代码如下:
protected void ButCourse_Click(object sender, EventArgs e) { // 基础输入校验 if(string.IsNullOrWhiteSpace(TxtCourseName.Text)) { ClientScript.RegisterStartupScript(GetType(), "alert", "alert('请输入课程名称');", true); return; } if(DropDownList1.SelectedValue == "select") { ClientScript.RegisterStartupScript(GetType(), "alert", "alert('请选择课程时长');", true); return; } // 解析课程费用,兼容千分位分隔符输入 int courseFee; string feeInput = TxtCourseFee.Text.Trim().Replace(",", ""); if(!int.TryParse(feeInput, out courseFee)) { ClientScript.RegisterStartupScript(GetType(), "alert", "alert('请输入有效的课程费用数字');", true); return; } string mainconn = ConfigurationManager.ConnectionStrings["Myconnection"].ConnectionString; // using块自动释放数据库连接 using(SqlConnection sqlconn = new SqlConnection(mainconn)) { string sqlquery = "Insert into [dbo].[Course] (CourseName, CourseFee, CourseDuration) values (@CourseName, @CourseFee, @CourseDuration)"; SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn); // 显式指定参数类型,传入对应类型的数值 sqlcomm.Parameters.Add("@CourseName", SqlDbType.NVarChar, 100).Value = TxtCourseName.Text.Trim(); sqlcomm.Parameters.Add("@CourseFee", SqlDbType.Int).Value = courseFee; sqlcomm.Parameters.Add("@CourseDuration", SqlDbType.NVarChar, 50).Value = DropDownList1.SelectedValue; sqlconn.Open(); sqlcomm.ExecuteNonQuery(); } ClientScript.RegisterStartupScript(GetType(), "alert", "alert('Course Added Successfully.!!');", true); TxtCourseName.Text = ""; TxtCourseFee.Text = ""; DropDownList1.SelectedIndex = 0; }
可选优化
- 前端可给课程费用输入框添加正则校验控件,限制用户仅能输入数字和千分位逗号,提前拦截非法输入
- 如果课程费用需要支持小数,需要同步将数据库字段类型、后端解析类型调整为
decimal,不要使用int类型存储 - 涉及金额类字段,数据库层面建议优先使用
decimal类型,避免整数类型无法存储角分精度的问题。
内容的提问来源于stack exchange,提问作者Fortune
相关产品推荐
相关产品推荐

