背景:
我有一个GridView,它通过DataSourceID从SqlDataSource填充。这些行显示了SQL视图中的一些摘要数据。单击一行后,我想将我的用户带到另一个带有DetailsView控件的页面,该控件将填充与所单击的行相关的完整值集。我的用户应该能够编辑数据,下载与记录关联的文件,并根据所述数据创建不同类型的新记录。
错误:
我为Clickable GridView行找到的所有示例最终都会出现错误Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.
当然,我不希望通过禁用事件验证来将我的网站暴露给漏洞。我需要能够获取所单击行的相关记录的主键,并在后续页面上对该数据执行操作,可能是通过DetailsView。我怀疑我的错误是我的设置的结果,这就是我将这些细节包括在内的原因。
我的问题:
**再次感谢伊卡洛斯的帮助
'Fetch the DataKey ("ID"), seems to work
Protected Sub RowBind(ByVal sender As Object, ByVal e As GridViewRowEventArgs) _
Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim datakey As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString()
End If
End Sub
'Handle button click
Protected Sub RowClick(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) _
Handles GridView1.RowCommand
If e.CommandName = "Select" Then
'Add to session variable; translate the index of clicked to Primary Key
Session.Add("DetailsKey", GridView1.DataKeys(e.CommandArgument).Value.ToString)
Response.Redirect("details.aspx")
End If
End Sub
和我的标记
<asp:GridView ID="GridView1" runat="server" DataSourceID="GridView1SDS"
DataKeyNames="ID" AllowPaging="True" AllowSorting="True">
'<!-- Styling -->
<Columns>
<asp:ButtonField ButtonType="Button" Text="Details" CommandName="Select" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="GridView1SDS" runat="server"
ConnectionString="<%$ ConnectionStrings:dbConnectionString %>"
SelectCommand="select * from viewRequestQueue">'<!-- An SQL View -->
</asp:SqlDataSource>
转发页面VB&amp;标记
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
GridView2SDS.SelectCommand = "select * from viewRequestQueue where ID = " _
+ Session.Item("DetailsKey").ToString
End If
End Sub
<asp:DetailsView ID="GridView2" runat="server" DataSourceID="GridView2SDS">
'<!-- Styling -->
</asp:DetailsView>
<asp:SqlDataSource ID="GridView2SDS" runat="server"
ConnectionString="<%$ ConnectionStrings:dbConnectionString %>">
</asp:SqlDataSource>
另外,请注意,如果在代码隐藏中处理数据源的SelectCommand
,则表示DataBind将覆盖标记中的<Columns>
。要解决这个问题,您应该在DataBind之前的代码中定义列。所以说我想在转发的页面中添加另一个ButtonField列(注意标记中没有提供SelectCommand),我在设置SelectCommand和执行DataBind之前添加了以下内容:
Dim id As New ButtonField()
id.ButtonType = ButtonType.Button
id.Text = "Load"
id.CommandName = "Select"
PubDetails.Columns.Add(id)
答案 0 :(得分:2)
您需要声明您在标记上绑定的项目的KeyNames。例如:
<asp:GridView id="grid" runat="Server" DataSourceID="YourSQLDataSource" DataKeyNames="ID,Name" />
在您的情况下,您似乎正在处理OnRowDataBound事件。您可以这样做以获取RowBound中的键:
If e.Row.RowType = DataControlRowType.DataRow Then
Dim datakey As String = GridView1.DataKeys(e.Row.RowIndex).Value.ToString() 'get the datakey
End If
您的第二个问题很难回答,因为您没有指定如何从客户端使用Javascript或从服务器端重定向用户。您还没有指定如何填充“详细信息”页面上的详细信息。您是否希望从URL读取参数并使用它从数据库中获取记录详细信息?