【问题标题】:How do I enable row selection in an ASP GridView without disabling EnableEventValidation?如何在 ASP GridView 中启用行选择而不禁用 EnableEventValidation?
【发布时间】:2022-11-03 21:29:30
【问题描述】:

我有一个包含 GridView 的 ASPX 页面。我希望能够从网格中选择一行,并根据所选行填充页面的另一部分。如果我在 <%@ Page %> 行中有 EnableEventValidation="false" 它可以工作,但我被告知由于安全问题我不能使用它。当我不包含它时,选择网格行会引发“无效的回发或回调参数”异常。

如何在不禁用事件验证的情况下实现行选择?

这是我的代码:

ASPX 页面:

<asp:GridView runat="server" ID="TheGrid" AutoGenerateColumns="false" DataKeyNames="id" EmptyDataText="No Data Found" AllowSorting="true">
    <Columns>                               
        <asp:BoundField DataField="FirstName" HeaderText="First Name" ReadOnly="true" SortExpression="FirstName" />
        <asp:BoundField DataField="LastName" HeaderText="Last Name" ReadOnly="true" SortExpression="LastName" />
        <asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="true" SortExpression="Email" />
    </Columns>
</asp:GridView>

ASPX.VB 代码:

Protected Sub TheGrid_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles TheGrid.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
        e.Row.Attributes("onclick") = Page.ClientScript.GetPostBackClientHyperlink(TheGrid, "Select$" & e.Row.RowIndex)
        e.Row.Attributes("style") = "cursor:pointer"
    End If
End Sub

Protected Overrides Sub Render(writer As HtmlTextWriter)
    ClientScript.RegisterForEventValidation("TheGrid")
    MyBase.Render(writer)
End Sub

请注意,当我选择一行时,异常会在 Page_Load 和 Render 之间的某处引发。

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    好的,让我们通过两种方式连接 GV。

    第一种方式,放入平面简按钮以单击行 (我们将在第二个示例中删除按钮并添加行单击)。

    所以,说这个简单的GV

    <div id="MyGridArea" runat="server" clientidmode="static">
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
            DataKeyNames="ID"
            CssClass="table table-hover" Width="60em" GridLines="None"
            ShowHeaderWhenEmpty="true">
            <Columns>
                <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
                <asp:BoundField DataField="LastName" HeaderText="LastName" />
                <asp:BoundField DataField="City" HeaderText="City" />
                <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
                <asp:BoundField DataField="Description" HeaderText="Description" />
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn myshadow"
                            OnClick="cmdEdit_Click" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </div>
    

    请注意我们是如何放入一个平面简按钮的。

    我们要在上面填写的代码是这样的:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        If Not IsPostBack Then
            LoadGrid()
        End If
    
    End Sub
    
    Sub LoadGrid()
        Dim strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName"
    
        GridView1.DataSource = Myrst(strSQL)
        GridView1.DataBind()
    
    End Sub
    

    现在我们有了这个:

    好的,所以下一部分是放入一个允许编辑一行的“div”区域。

    所以,再次,相当多的计划简控制。

    我们可以在编辑时“隐藏”网格,并显示编辑区域 div。

    但是,我经常使用 jQuery.UI。确实相当于简单的隐藏/显示代码,但是jQuery.UI 将相同的 div 变成了一个不错的弹出区域。

    因此,该 div 区域可能如下所示:

            <div id="EditRecord" runat="server" style="float: left; display: none" clientidmode="Static">
    
                <br />
                <div style="float: left" class="iForm">
    
                    <label>HotelName</label>
                    <asp:TextBox ID="txtHotel" runat="server" f="HotelName" Width="280">
                    </asp:TextBox>
                    <br />
                    <label>First Name</label>
                    <asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140"></asp:TextBox>
                    <br />
                    <label>Last Name</label>
                    <asp:TextBox ID="tLN" runat="server" f="LastName" Width="140"></asp:TextBox>
                    <br />
    
                    <label>City</label>
                    <asp:TextBox ID="tCity" runat="server" f="City" Width="140"></asp:TextBox>
    
                    <br />
                    <label>Province</label><asp:TextBox ID="tProvince" runat="server" f="Province" Width="75"></asp:TextBox>
                </div>
    

    等等等等等等

    所以,现在让我们连接上面的按钮。

    该按钮将很简单:

    获取当前网格行

    获取PK id

    加载 div 并显示。

    所以,该代码是这样的:

    Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
    
        Dim btn As Button = sender
        Dim gRow As GridViewRow = btn.NamingContainer
        EditRow(gRow.RowIndex)
    
    End Sub
    
    Sub EditRow(rowNum As Integer)
    
        Dim intPK As Integer = GridView1.DataKeys(rowNum).Item("ID")
        Dim strSQL As String = "SELECT * FROM tblHotelsA WHERE ID = " & intPK
    
        Dim rstData As DataTable = Myrst(strSQL)
    
        ' load up our edit div
        fLoader(Me.EditRecord, rstData.Rows(0))
        ViewState("PK") = intPK
    
        ScriptManager.RegisterStartupScript(Me.Page, Page.GetType, "mypopedit", "popedit()", True)
    
    End Sub
    

    如前所述,我从 jQuery.UI 添加了一个弹出窗口,但我们可以只使用普通的 jane“div”并隐藏/显示网格并显示编辑区域(或者像你一样,让编辑区域处于全视图)。

    (fLoader 是我前段时间建立的一个例程 - 我喜欢非常厌倦一遍又一遍地输入代码来填写文本框等,所以对于任何文本框等,我使用一个名为 f= 的“虚构”属性“数据库列名称”,并且该例程只是循环表单上的控件并填写它们。没有区别然后将简单的代码分配给控件,但是使用此代码,我可以一遍又一遍地重复使用它。

    所以,我们现在看到,得到这个:

    好的,所以唯一的下一个目标是添加行点击 (而不是使用那个编辑按钮)。

    因此,我们需要的只是一个获取当前行索引的例程,并调用我们上面的编辑行例程。

    因此,我们使用行数据绑定,并以这种方式添加该单击事件。

    但是,请注意上面的按钮单击如何获取当前行。那个漂亮的短代码适用于转发器、列表视图等(我们使用命名容器)。

    但是,如果你想要一行点击来代替那个按钮?

    然后在行数据绑定上,添加以下代码:

    Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
    
        If e.Row.RowType = DataControlRowType.DataRow Then
    
            e.Row.Attributes.Add("onclick",
                 "__doPostBack('myrowedit'," & e.Row.RowIndex & ")")
    
        End If
    
    End Sub
    

    在我们的页面加载事件中,我们有这个:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        If Not IsPostBack Then
            LoadGrid()
        Else
            If Request("__EVENTTARGET") = "myrowedit" Then
                EditRow(Request("__EVENTARGUMENT"))
            End If
        End If
    
    End Sub
    

    还有一个方便的花花公子例程,它根据我上面使用的 SQL 返回一个表:

    Public Function Myrst(strSQL As String) As DataTable
    
        Dim rstData As New DataTable
        Using mycon As New SqlConnection(My.Settings.TEST4)
    
            Using cmdSQL As New SqlCommand(strSQL, mycon)
                mycon.Open()
                rstData.Load(cmdSQL.ExecuteReader)
            End Using
    
        End Using
    
        Return rstData
    
    End Function
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 2014-12-11
      • 2020-06-15
      • 2012-12-07
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      相关资源
      最近更新 更多