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

时间:2014-11-10 11:53:19

标签: c# sql asp.net barcode

我正在编写一个小型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 info,Boolean

     

parseDecimal)+11177559 System.Number.ParseDecimal(String value,   NumberStyles选项,NumberFormatInfo numfmt)+172
  System.Convert.ToDecimal(String value,IFormatProvider provider)+67
  System.String.System.IConvertible.ToDecimal(IFormatProvider provider)   +10 System.Convert.ChangeType(Object value,Type conversionType,IFormatProvider provider)+11043185
  System.Data.SqlClient.SqlParameter.CoerceValue(Object value,MetaType   destinationType,Boolean& coercedToDataFeed,

     

布尔&安培; typeChanged,Boolean allowStreaming)+5332823

     

[FormatException:无法将参数值从String转换为   十进制。] System.Data.SqlClient.SqlParameter.CoerceValue(Object   value,MetaType destinationType,Boolean& coercedToDataFeed,

     

布尔&安培; typeChanged,Boolean allowStreaming)+5331815
  System.Data.SqlClient.SqlParameter.GetCoercedValue()+ 185   System.Data.SqlClient.SqlParameter.Validate(Int32 index,Boolean   isCommandProc)+102
  System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser解析器,   SqlParameterCollection参数)+201
  System.Data.SqlClient.SqlCommand.BuildExecuteSql(的CommandBehavior   behavior,String commandText,SqlParameterCollection

     

参数,_SqlRPC& rpc)+237
  System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean

     

returnStream,布尔异步,Int32超时,任务&任务,布尔值   asyncWrite,SqlDataReader ds)+1421
  System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior   cmdBehavior,RunBehavior runBehavior,Boolean

     

returnStream,String方法,TaskCompletionSource 1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +177
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
1   completion,String methodName,Boolean

     

sendToPipe,Int32 timeout,Boolean asyncWrite)+208
  System.Data.SqlClient.SqlCommand.ExecuteNonQuery()+ 163 3   PosSystem.Stock.addStock.btnAdd_Click(Object sender,EventArgs e)in   路径\ add.aspx.cs:33个
  System.Web.UI.WebControls.Button.OnClick(EventArgs e)+9615682
  System.Web.UI.WebControls.Button.RaisePostBackEvent(字符串   eventArgument)+103
  System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(字符串   eventArgument)+10
  System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler   sourceControl,String eventArgument)+13
  System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)   +35 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)

     

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();
    }

2 个答案:

答案 0 :(得分:2)

这一行...

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

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

尝试将其解析为小数第一

答案 1 :(得分:0)

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

我认为您仍然没有关注真正的问题,即您依赖于未经验证的数据强制。你当然可以修剪任何空白区域 - 但是如果你自己进行转换,你可以覆盖远远超过试图抛弃输入问题而转而编写更多防御性代码。

我通常会让“Sandbox”准备在应用程序之外测试这样的东西。看看这段代码......它远非完美,但是它说明了一些可以传递给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