1

Pulling my hair out, some help would be great.

I'm loading a GridView in ASP dynamically populating the results from an SQL Statement. This page is for general queries so header names are pulled from the query results, no template.

What I'm trying to do is when a header is called i.e.. SSN (sensitive data column) I want to go through each cell in this specific column and mask the field. Example: "###-##-####". before the page is displayed, and so all changes are kept on each page change and when the GridView is re-binded.

I looked over a couple events like GridView1_RowCreated, GridView1_OnDataBound

However, whenever I search for the header.text it's always empty! I can change it and set it, but it's never populated in these events. This leads me to believe I’m looking in the wrong place to do this update.

ie:

Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)

    Dim header As String

    ' DataControlRowType.DataRow - also tried this with checking HeaderText too.
    If e.Row.RowType = DataControlRowType.Header Then

        For columnIndex As Integer = 0 To e.Row.Cells.Count - 1 Step 1
            header = e.Row.Cells(columnIndex).Text                
            Response.Write(header) ' Empty
            Response.Write("Cell") ' Will Display this for each header cell. 
            header = String.Empty         
        Next

    End If

End Sub

Would I need to do this on the Page_Load or PreRender? Any ideas/examples would be great.
Thanks for your help.

2
  • Do this in Grid View PreRender event. Commented Dec 14, 2013 at 11:50
  • it's seems that with AutoGeneratedColumns = True on the GridView, that the Header cells are still not populated with Cell or HeaderText in PreRender or OnPreRender. I'm really at a loss now. Commented Dec 15, 2013 at 22:51

1 Answer 1

2

If you can determine the special column by its header text you can find out the column index and then, when you found the specific column change the cell's text in the RowDataBound event.

This worked in my test:

ASPX:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication1._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
      <div>
        <asp:GridView runat="server" ID="GridView1" />
      </div>
    </form>
</body>
</html>

Code Beding:

Partial Public Class _Default
    Inherits Page

    Private _specialColumnName As String = "DEF"
    Private _specialColumnIndex As Integer = -1

    Private ReadOnly Property Data() As DataTable
        Get
            If Session("Default.Data") Is Nothing Then
                Dim value = New DataTable()

                Using connection = New SqlClient.SqlConnection("your_connection_string")
                    Using command = connection.CreateCommand()
                        command.CommandText = "SELECT * FROM your_table"

                        Using adapter = New SqlClient.SqlDataAdapter(command)
                            adapter.Fill(value)
                        End Using
                    End Using
                End Using

                'value.Columns.Add("ABC", GetType(String))
                'value.Columns.Add("DEF", GetType(Integer))
                'value.Columns.Add("GHI", GetType(Boolean))

                'value.Rows.Add("A", 1, True)
                'value.Rows.Add("B", 2, False)
                'value.Rows.Add("C", 3, False)

                Session("Default.Data") = value
            End If

            Return CType(Session("Default.Data"), DataTable)
        End Get
    End Property

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        GridView1.DataSource = Data
        GridView1.DataBind()
    End Sub

    Private Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles GridView1.RowDataBound
        If e.Row.RowType = DataControlRowType.Header Then
            For index As Integer = 0 To e.Row.Cells.Count - 1
                If e.Row.Cells(index).Text = _specialColumnName Then
                    _specialColumnIndex = index
                    Return
                End If
            Next
        ElseIf _specialColumnIndex > -1 AndAlso e.Row.RowType = DataControlRowType.DataRow Then
            e.Row.Cells(_specialColumnIndex).Text = "###"
        End If
    End Sub

End Class
Sign up to request clarification or add additional context in comments.

10 Comments

Thank you for the reply. This still seems to be the problem. 'e.Row.Cells(index).Text' is always empty, so there is nothing to test against. The query is select * from [ThisTable] and the Gridview is set for AutogenerateColumns = True, and there are no Bound Fields in the <asp: columns becasue it's all dynamic. I'm starting to think this is not an ability of .net to do this dynamically which is a shame.
I updated my answer and added a complete example (very simple but should be essentially the same thing you have described). Could you please test if this simple example works for you? Try to test with the manually created data (comment out the sql stuff and uncomment the data table generation code) and with a simple sql statement. As I said, this works for me. Maybe you have some special case? What kind of data source do you use? A DataTable or something else? Generally ASP.NET is capable of your described task.
Looks like that did the trick. Thank you very much!! Not sure if it's a .NET 2.0 thing but I had to prefix the types ie, DataTable and SQLClient with System.Data. first to get it working. Wish I thought of that sooner, I thought those types were missing in ASP.NET I'm actually mixing a bit of Classic ASP with .NET to get some new features in this old hunk of junk. I appreciate the kind help.
The DataTable class is in the System.Data namespace and the SqlConnection, SqlCommand and so on are in the System.Data.SqlClient namespace. So you either have to prefix the types with the according namespace or add a Using System.Data and Using System.Data.SqlClient on top of your code file; alternatively you can add namespaces on a project level under "References" in the project settings. In fact, normally, VB.NET projects have the System.Data namespace included on the project level from the very beginning. Maybe that may be turned of by a setting...
I believe the System.Data is not included becasue i'm not using a asp.net project. i'm hand writting just a aspx page that i'm plugging into Classic ASP site. Instead of Classes and Code Behind i'm just doing the function in <script> and using <asp: tags. makes it easy and work nicely. Thanks for the tip. i''ll look into a project, might make things a little easier.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.