我正在编写一个小型Web应用程序,我想使用Web表单向我的数据库添加一些细节。我使用asp.net和c#来创建这个Web应用程序和visual studio 2013作为开发工具。我正在使用条形码扫描仪扫描产品的条形码。因为我不能在我的用户界面中包含截图,我有3个标签,3个文本框(条形码,描述,价格),一个添加按钮,我创建了一个数据库来保存我的详细信息。我在数据库中的3个列是Barcode
,Description
,Price
,其数据类型为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,BooleanparseDecimal)+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,BooleanreturnStream,布尔异步,Int32超时,任务&任务,布尔值 asyncWrite,SqlDataReader ds)+1421
System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior cmdBehavior,RunBehavior runBehavior,BooleanreturnStream,String方法,TaskCompletionSource
1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +177
1 completion,String methodName,Boolean
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSourcesendToPipe,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();
}
答案 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