【问题标题】:rowUpdating seems to fire off twice - erroring out with too many arguments the second timerowUpdating 似乎触发了两次 - 第二次出现太多参数错误
【发布时间】:2023-03-16 19:38:01
【问题描述】:

我有一个试图更新行的gridview。如果我在行更新事件上放置一个断点,它会在第一次被击中并且行更新成功。当我继续单步执行该代码时,第二次没有命中,但是我得到一个异常,即来自该更新的存储过程有太多参数并引发错误。

我确实将 autoeventwireup 设置为 true。这是一个问题吗?我尝试将其设置为 false,但我在 page_load 中发生了其他事情,这些事情没有发生并破坏了页面。另外,从我读过的内容来看,这可能不是问题。任何帮助是极大的赞赏!

这是错误的堆栈跟踪

[SqlException (0x80131904): Procedure or function RecordingUpdateName has too many arguments specified.]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +2084358
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +5096328
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +234
   System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2294
   System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +215
   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
   System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +178
   System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +137
   System.Web.UI.WebControls.SqlDataSourceView.ExecuteDbCommand(DbCommand command, DataSourceOperation operation) +394
   System.Web.UI.WebControls.SqlDataSourceView.ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues) +697
   System.Web.UI.DataSourceView.Update(IDictionary keys, IDictionary values, IDictionary oldValues, DataSourceViewOperationCallback callback) +95
   System.Web.UI.WebControls.GridView.HandleUpdate(GridViewRow row, Int32 rowIndex, Boolean causesValidation) +1226
   System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +855
   System.Web.UI.WebControls.GridView.OnBubbleEvent(Object source, EventArgs e) +95
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
   System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source, EventArgs e) +121
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
   System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +125
   System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +169
   System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +9
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +176
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563

还有:

<asp:GridView ID="grdvwRecordings" runat="server"
    DataSourceID="sqldataRecordings"
    EmptyDataText="No recordings have been saved. Select Call Now below. "
    DataKeyNames="RecordingID"
    onrowdeleting="grdvwRecordings_RowDeleting"
    onrowupdating="grdvwRecordings_RowUpdating"
    onrowediting="grdvwRecordings_RowEditing"
    AutoGenerateColumns="False"
    onrowdatabound="grdvwRecordings_RowDataBound">

    <Columns>
        <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
        <asp:TemplateField HeaderText="Recording">
            <ItemTemplate>
                <asp:Label ID="lblRecordingName" Text='<%# Bind("Name") %>' runat="server"></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="txtRecordingName" Text='<%# Bind("Name") %>' runat="server"></asp:TextBox>
            </EditItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Date Recorded">
            <ItemTemplate>
                <asp:Label ID="lblDateRecorded" Text='<%# Bind("EntryDate") %>' runat="server"></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Duration">
            <ItemTemplate>
                <asp:Label ID="lblDuration" Text='<%# Bind("Duration") %>' runat="server"></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<asp:SqlDataSource ID="sqldataRecordings" SelectCommand="[RecordingSelectByClient]"
   SelectCommandType="StoredProcedure" runat="server"
   ConnectionString="<%$ ConnectionStrings:VB %>"
   onselecting="AddClientIDParameter_Selecting"
   UpdateCommand="RecordingUpdateName"
   UpdateCommandType="StoredProcedure"
   DeleteCommand="RecordingDelete"
   DeleteCommandType="StoredProcedure">

    <UpdateParameters>
        <asp:Parameter Name="RecordingName" Type="String" />
        <asp:Parameter Name="RecordingID" Type="Int32" />
    </UpdateParameters>

</asp:SqlDataSource>

还有:

protected void grdvwRecordings_RowUpdating(object sender, GridViewUpdateEventArgs e)
{

   this.sqldataRecordings.UpdateParameters["RecordingID"].DefaultValue = e.Keys["RecordingID"].ToString();
   this.sqldataRecordings.UpdateParameters["RecordingName"].DefaultValue = e.NewValues["Name"].ToString();

    this.sqldataRecordings.Update();
}

【问题讨论】:

  • 更新存储过程的调用签名是什么?
  • [dbo].[RecordingUpdateName] @RecordingID int,@RecordingName varchar(100)
  • 该程序第一次运行良好。我只是不知道为什么它会再次被调用并失败

标签: c# asp.net gridview


【解决方案1】:

请尝试以下方法:

从 GridView 属性中删除 onrowupdating="grdvwRecordings_RowUpdating"

SqlDataSource 标记中,将UpdateParameters 替换为:

<UpdateParameters>
    <asp:QueryStringParameter Name="RecordingName" QueryStringField="Name" Type="String" />
    <asp:QueryStringParameter Name="RecordingID" QueryStringField="RecordingID" Type="String" />
</UpdateParameters>

我认为发生的情况是您在 GridView 中指定了一次更新命令(使用 OnRowUpdated 属性)并在 SqlDataSource 中指定了一次。

编辑:
正如 Tim Brooks 在下面的 cmets 中指出的那样,他需要使用 &lt;%# Eval("Name") %&gt; 而不是 Bind,因为绑定的字段会自动作为参数添加到更新命令中。

另外,我不会担心通过进行我建议的更改来暴露您的主键。由于这是一个 Web 应用程序,并且您正在从 GridViewUpdateEventArgs 获取 RecordingID,因此您已经将信息传递到 ViewState 中的用户计算机。如果这是不可接受的,我建议您加密 ViewState。可能会有明显的性能影响,但 ViewState 将不会被读取。
有关详细信息,请参阅Page.ViewStateEncryptionMode PropertyEncrypt ViewState in ASP.NET 2.0Securing View State

如果您需要 ViewState 入门,您可以从 this post 开始,但我相信还有很多其他好的。

【讨论】:

  • 同样的错误,但是通过删除 onrowupdating 更改永远不会影响数据库。如果这种技术可行,我会在查询字符串中公开我的主键,对吗?我在后面的代码中设置了参数以避免这种情况。
  • 我在选择时在 sql 数据源中添加了一个参数 - onselecting="AddClientIDParameter_Selecting"。可以以某种方式调用吗?由于 onrowupdating 有效,我很想弄清楚如何保留它并删除第二次调用它的任何内容。谢谢你的帮助
  • 我尝试将信息移动到后面的代码中,并从 aspx 中删除了更新参数和命令,但它的行为方式相同。 this.sqldataRecordings.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure; this.sqldataRecordings.UpdateCommand = "RecordingUpdateName"; this.sqldataRecordings.UpdateParameters.Add("RecordingID", DbType.Int32, e.Keys["RecordingID"].ToString()); this.sqldataRecordings.UpdateParameters.Add("RecordingName", e.NewValues["Name"].ToString());
  • 我想通了。首先,我调用了两次更新,所以我从代码隐藏中删除了所有更新代码。其次,我试图只更新一个字段,但 gridview 中有 3 个字段,我在每个字段上都使用 Bind。 Bind 作为双向参数工作,在选择时读取并在更新时用作参数。这就是我得到很多参数错误的原因。一旦我在字段上将绑定更改为 Eval,我就没有更新它了。感谢您的帮助
  • @TimBrooks 很高兴你知道了。我将更新我的答案以包括 Bind/Eval 事情(所以如果其他人有问题,他们知道你做了什么来解决它)。
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
相关资源
最近更新 更多