尝试将字符串写入数据库时发生FormatException

本文关键字:FormatException 数据库 字符串 | 更新日期: 2023-09-27 18:29:47

我正在编写一个小型web应用程序,我想使用web表单将一些细节添加到我的数据库中。我正在使用asp.net和c#创建这个web应用程序和visual studio 2013作为开发工具。我正在使用条形码扫描仪扫描产品的条形码。因为我不能包含用户界面的屏幕截图,所以我有3个标签、3个文本框(条形码、描述、价格)、一个添加按钮,并且我创建了一个数据库来保存我的详细信息。我在数据库中的3列是BarcodeDescriptionPrice,它们的数据类型是varchar(50)varchar(50)decimal(10,2)。当我运行页面并扫描条形码时,我得到一个异常:

System.FormatException:输入字符串的格式不正确。

我试过不用条形码扫描仪,把条形码放在键盘上,效果很好。

以下是异常的更多细节:

"/"应用程序中的服务器错误

输入字符串的格式不正确。描述:未处理的在执行当前web请求期间发生异常。请查看堆栈

跟踪以获取有关错误及其来源的更多信息代码。

异常详细信息:System.FormatException:输入字符串不在正确的格式。

来源错误:

第31行:con.Open();第32行:第33行:
da.InsertCommand.ExecuteNonQuery();第34行:第35行:
con.Close();

源文件:path.aspx。cs行:33

堆栈跟踪:

[FormatException:输入字符串的格式不正确。]
System.Number.StringToNumber(String str,NumberStyles选项,NumberBuffer&number,NumberFormatInfo信息,布尔

parseDecimal)+11777559 System.Number.parseDecimal(字符串值,NumberStyles选项,NumberFormatInfo numfmt)+172
System.Convert.ToDecimal(字符串值,IFormatProvider提供程序)+67
System.String.System.IConvertible.ToDecimal(IFormatProvider提供程序)+10 System.Convert.ChangeType(Object value,Type conversionType,IFormatProvider provider)+11043185
System.Data.SqlClient.SqlParameter.CorceValue(对象值,MetaTypedestinationType,布尔型&强制ToDataFeed,

布尔运算&typeChanged,Boolean allowStreaming)+5332823

[FormatException:未能将参数值从字符串转换为小数。]System.Data.SqlClient.SqlParameter.CorceValue(对象value,MetaType destinationType,Boolean&强制ToDataFeed,

布尔运算&typeChanged,布尔值allowStreaming)+5331815
System.Data.SqlClient.SqlParameter.GetCoercedValue()+185
System.Data.SqlClient.SqlParameter.Valide(Int32索引,布尔值isCommandProc)+102
System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser解析器,SqlParameterCollection参数)+201
System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior行为,字符串命令文本,SqlParameterCollection

参数,_SqlRPC&rpc)+237
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehaviorcmdBehavior、RunBehavior RunBehavior和布尔

returnStream,布尔异步,Int32超时,任务&任务,布尔asyncWrite,SqlDataReader ds)+1421
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehaviorcmdBehavior、RunBehavior RunBehavior和布尔

returnStream,String方法,TaskCompletionSource 1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +177
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
1完成,字符串methodName,布尔

sendToPipe,Int32超时,布尔异步写入)+208
System.Data.SqlClient.SqlCommand.ExecuteNonQuery()+163
PosSystem.Stock.addStock.btD_Click(对象发送方,EventArgs e)路径''add.aspx.cs:33
System.Web.UI.WebControls.Button.OnClick(EventArgs e)+9615682
System.Web.UI.WebControls.Button.RisePostBackEvent(字符串eventArgument)+103
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(字符串eventArgument)+10
System.Web.UI.Page.RisePostBackEvent(IPostBackEventHandlersourceControl,String eventArgument)+13
System.Web.UI.Page.RisePostBackEvent(NameValueCollection postData)+35 System.Web.UI.Page.ProcessRequestMain(布尔值包括同步点之前的阶段,布尔值包括异步点之后的阶段)

+1724

任何人都知道为什么会这样,我该怎么解决?

这是我点击按钮时的代码:

    protected void btnAdd_Click(object sender, EventArgs e)
    {
        int y;
        da.InsertCommand = new SqlCommand("INSERT INTO Products VALUES(@Barcode,@Description,@Price)", con);
        da.InsertCommand.Parameters.Add("@Barcode", SqlDbType.VarChar).Value = txtBarcode.Text;
        da.InsertCommand.Parameters.Add("@Description", SqlDbType.VarChar).Value = txtDescription.Text;
        da.InsertCommand.Parameters.Add("@Price", SqlDbType.Decimal).Value = txtPPrice.Text;
        con.Open();
        da.InsertCommand.ExecuteNonQuery();
        con.Close();
    }

尝试将字符串写入数据库时发生FormatException

此行。。。

da.InsertCommand.Parameters.Add("@Price", SqlDbType.Decimal).Value = txtPPrice.Text;

似乎是个问题。您正试图将文本保存到十进制字段中。如果sql驱动程序可以将字符串的值转换为十进制,则它可以工作,但在这种情况下它会失败。可能是因为价格字符串包含货币格式(例如£、$)。

尝试将其解析为十进制第一

我意识到这是一个老问题,但我一直遇到这样的代码,问题是允许.NET和Sql强制值。

我认为你仍然没有关注真正的问题,那就是你依赖于对你没有验证的数据的强制。然而,你当然可以修剪任何空白——如果你自己进行转换,你会比试图消除输入问题而编写更多防御性代码覆盖更多的领域。

我通常会准备一个"沙盒",以便在应用程序之外测试类似的东西。看看这个代码。。。然而,它还远远不够完美——它展示了一些可以传递给TryParse的标志,这将为您省去大量的头痛和沮丧。

    Dim theProblemWithTheData As String = String.Format("$-123.45{0}", vbCrLf)
Dim dontDoThis As New System.Data.SqlClient.SqlParameter("fakeParameter",
                                                         SqlDbType.Decimal)
Dim doThis As New System.Data.SqlClient.SqlParameter("betterFakeParameter",
                                                     SqlDbType.Decimal)
Dim doThisValue As Decimal
Try
  dontDoThis.Value = theProblemWithTheData
  Dim success As Boolean = Decimal.TryParse(theProblemWithTheData,
                                            System.Globalization.NumberStyles.Any,
                                            System.Globalization.CultureInfo.CurrentCulture,
                                            doThisValue)
  If success Then
    doThis.Value = doThisValue
  End If
Catch ex As Exception
  Dim exInfo As String = ex.ToString
End Try