tags:

views:

346

answers:

3

We're creating a demonstration mode for our web application. We're going about this by creating new user that is tied to a real client, showing all of their data, but filtering certain fields to be non-identifiable (names, important numbers, etc...)

The weird part here is that the data is correctly filtered for standard "show one" pages where I am calling the first function. When I try to call the second on a list page, the filter doesn't work. I have stepped through the functions, and it appears that in the first function, the values are being set, but are being reset back to the original values when the foreach iterates to the next row.

List mask is the list of column names that should be masked and is statically defined in the model.

public static void ApplyDemoMask(DataRow row, List<string> mask)
{
    foreach (DataColumn column in row.Table.Columns)
    {
        if (mask.Contains(column.ColumnName))
        {
            if (column.ColumnName == "ClientName")
                row[column] = "Demo Client";
            // More fields follow...
        }
    }
}

public static void ApplyDemoMask(FindResponse response, List<string> mask)
{
    foreach (DataRow row in response.ResultTable.Rows)
        ApplyDemoMask(row, mask);
}

I appreciate any help that can be given. I'm kind of dumb when it comes to System.Data for some reason.

Edit: If it helps, when my debugger lands on the "}" in the second function, row["ClientName"] is "Demo Client" as it should be, but response.ResultTable.Rows[0]["ClientName"] is "The Original Client". Weird!

Edit: When binding to my grid, I have to specify column names. For one, we're using ASP.NET MVC and are using a custom control we wrote to help us transition from ASP.NET. Secondly, we have a lot of template fields. There can't be any huge, sweeping changes to this web application shares code with a pretty big WinForms line-of-business application.

A: 

Try adding a call to

Row.AcceptChanges()

after the ForEach statement in ApplyDemoMask.

It seems your datagrid is binding to the current version of the rows, not the proposed version. Here are some references about rowstate for datarows in a datatable.

Tom A
No cigar. I had tried adding the call to the end of the first function earlier today, and also tried ResultTable.AcceptChanges() as well.
Stuart Branham
@Stuart: What is type FindResponse? Is that inherited from datatable?
Tom A
@Stuart -- oops, i see. It contains a member datatable.
Tom A
I believe the above comment subconsciously led me in the right direction. Thanks!
Stuart Branham
A: 

Maybe you deleted and added the same records many times. so you are updating the deleted one. change second method as :

public static void ApplyDemoMask(FindResponse response, List<string> mask)
{
    foreach (DataRow row in response.ResultTable.Rows)
    {
        if (row.RowState != DataRowState.Deleted)
        {
            ApplyDemoMask(row, mask);
        }
    }
}

or like that :

public static void ApplyDemoMask(FindResponse response, List<string> mask)
{
    response.ResultTable.AcceptChanges();
    foreach (DataRow row in response.ResultTable.Rows)
    {
        ApplyDemoMask(row, mask);
    }
}

hope this helps.

Canavar
A: 

I am an absent-minded imbecile!

Check out ResultTable's definition...

public DataTable ResultTable { get { return this[_resultKey]; } }
public DataTable this[string tableName]
{
    get { return _data.Tables[tableName].DefaultView.ToTable(); }
}

I was making changes to the DataTable's DefaultView.ToTable(), which was being lost when going back to read ResultTable again. I completely forgot about this behavior and how our internal FindResponse class worked. It makes sense for our application, so I just added a similar BaseTable accessor that does not filter through DataTable.DefaultView, made my changes to that, and everything worked.

Thanks for the responses and sorry I didn't provide enough information.

Stuart Branham