Перенаправление строки GridView на предварительно заполненный DetailsView при нажатии кнопки

#asp.net #vb.net #gridview #detailsview

#asp.net #vb.net #gridview #detailsview

Вопрос:

Фон:

У меня есть GridView, который заполняется из SqlDataSource через DataSourceID. В строках отображаются некоторые сводные данные из представления SQL. После нажатия строки я хотел бы перевести своего пользователя на другую страницу с элементом управления DetailsView, который заполняется полным набором значений из базы данных, связанных с выбранной строкой. Мой пользователь должен иметь возможность редактировать данные, загружать файлы, связанные с записью, и создавать новую запись другого типа на основе указанных данных.

Ошибка:

Все примеры, которые я нашел для интерактивных строк GridView, заканчиваются некоторой вариацией ошибки Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.

Естественно, я не хочу подвергать свой сайт уязвимостям, отключив проверку событий. Мне нужно иметь возможность получить первичный ключ связанной записи, связанной с выбранной строкой, и выполнять операции с этими данными на последующей странице, возможно, через DetailsView. Я подозреваю, что мои ошибки являются результатом моей настройки, поэтому я включил эти данные.

Мои вопросы:

  1. Как мне получить первичный ключ выбранной строки?
  2. Как мне, onclick, перейти на страницу «подробности» с предварительно заполненной формой, содержащей данные из записи строки, на которую был нажат?

ВОТ ПОЛНОЕ РЕШЕНИЕ

** еще раз спасибо за помощь Icarus

 '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 и разметка

 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 для вашего источника данных обрабатывается в codebehind, это означает, что привязка данных перезапишет вашу <Columns> разметку. Чтобы обойти это, вы должны определить столбцы в коде перед привязкой данных. Допустим, я хотел добавить еще один столбец ButtonField на мою перенаправленную страницу (обратите внимание, что команда SelectCommand не указана в разметке), я добавил следующее перед установкой команды SelectCommand и выполнением привязки данных:

 Dim id As New ButtonField()
id.ButtonType = ButtonType.Button
id.Text = "Load"
id.CommandName = "Select"
PubDetails.Columns.Add(id)
  

Комментарии:

1. Знакомы ли вы со свойством DataKeys для GridView?

2. @TheGeekYouNeed: только то, что я прочитал в API, а это немного. Я бы не знал, как реализовать это в коде>. < Полагаю, мне нужно создать пользовательскую команду? Потому что ни «выбрать», ни «редактировать», ни «удалить», ни «обновить» — это то, что мне нужно сделать. Опять же, не знаю, как это реализовать. Вот почему я здесь. С уважением 😉

Ответ №1:

Вам необходимо объявить ключевые имена элементов, которые вы привязываете к своей разметке. Например:

 <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-адреса и использовать его для получения сведений о записи из базы данных?

Комментарии:

1. Мы будем лучшими друзьями, если ты продолжишь помогать мне, хе-хе. Я действительно ценю это. Что ж, ваш код отлично работает, но это не добавляет интерактивности. Когда я пытаюсь объединить ClientScript фрагмент с вашим, я снова получаю эту неприятную ошибку. Что касается второй части моего вопроса, я полностью открыт для предложений. Для меня это новая территория.

2. Бах!! В любом случае, вверните глупые интерактивные строки. На данный момент я был бы рад просто прочитать нажатие кнопки, получить связанный первичный ключ из строки (который я, кажется, получаю из вашего кода) и перенаправить на страницу, где детали можно увидеть вместе с предварительно заполненной формой, или, как вы предлагаете, обрабатыватьэто. Мне просто нужна функциональность, упомянутая в моем сообщении. Извините, что это так много работы, я полагаю, часто приходится изучать новую структуру. Большое спасибо за вашу постоянную помощь: D

3. Аргументы!!! Буквально, лол. Что бы я ни делал, я не могу вернуть ключ данных, который мы проиндексировали в вашем коде в моем событии RowCommand : (

4. @Chiramisu опубликуйте свою разметку и свой код, и я посмотрю, смогу ли я помочь вам с некоторыми идеями / кодом

5. Долбаный WEWT!! Я наконец-то все понял. Сначала я выяснил, как пересылать значение, используя переменную сеанса и ответ. Перенаправление, затем я понял, как захватить первичный ключ из индекса записи выбранной строки, теперь для предварительного заполнения данных на основе ключа. Ууууу!! Еще раз спасибо, приятель, я бы дал тебе дополнительные плюсы, если бы мог, так как ты направил меня в правильном направлении 😉