Search code examples
c#asp.netcsvdatatablepersistence

Changes to DataTable not persisting when exporting DataTable to .CSV file in ASP.NET


The following code sends just last row of my DataTable in .csv file.I can't see here where I'm wrong, I'm new in this, please help me.

DataTable dt22 = new DataTable(); 
dt22.Columns.Add("Tasks");
DataRow dr = dt22.NewRow(); 
dr[0] = TextBox2.Text;

dt22.Rows.Add(dr);

GridView1.DataSource = dt22; 
GridView1.DataBind();

Session["Data"] = dt22;

StringBuilder sb = new StringBuilder();

IEnumerable<string> columnNames = dt22.Columns.Cast<DataColumn>().
                                  Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));

foreach (DataRow row in dt22.Rows)
{
    IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
    sb.AppendLine(string.Join(",", fields));
}

File.WriteAllText(@"c:\Tasks.csv", sb.ToString());

Solution

  • Update:

    It's difficult to understand exactly the problem but I think it is with data persistence between post-backs. When the user adds a row to the grid are you updating the underlying data source which you then go on to create the CSV with?

    It looks like you are trying to use Session to persist data, did you try something like this:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
            InitialDataLoad();
    }
    
    private void InitialDataLoad()
    {
        var dt = new DataTable();
        dt.Columns.Add("Tasks");
        dt.Columns.Add("AnotherColumn");
    
        var dr = dt.NewRow();
        dr[0] = "task1";
        dr[1] = "c1";
        dt.Rows.Add(dr);
    
        GridView1.DataSource = dt;
        GridView1.DataBind();
    
        Session["dt"] = dt;
    }
    
    protected void Button1_Click(object sender, EventArgs e)
    {
        // adds a row
    
        var dt = Session["dt"] as DataTable;
    
        if (dt != null)
        {
            var dr = dt.NewRow();
            dr[0] = "anothertask";
            dr[1] = "c2";
            dt.Rows.Add(dr);
    
            GridView1.DataSource = dt;
            GridView1.DataBind();
    
            Session["dt"] = dt;
        }
    }
    
    protected void Button2_Click(object sender, EventArgs e)
    {
        // create csv
    
        var dt = Session["dt"] as DataTable;
    
        var sb = new StringBuilder();
    
        IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
                                          Select(column => column.ColumnName);
    
        sb.AppendLine(string.Join(",", columnNames));
    
        foreach (DataRow row in dt.Rows)
        {
            IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
            sb.AppendLine(string.Join(",", fields));
        }
    
        File.WriteAllText(@"c:\Tasks.csv", sb.ToString());
    }
    

    Older answer:

    The final loop of your code is capable of printing more than just the last row, so I don't see a problem there. The problem may be with what you are expecting to be in dt22. It looks like you are only adding a single row of data to the dt22 DataTable at the top of the code, so how many rows are you expecting?

    Here's an example with more data using your same code:

    DataTable dt22 = new DataTable();
    dt22.Columns.Add("Tasks");
    dt22.Columns.Add("AnotherColumn");
    
    DataRow dr = dt22.NewRow();
    dr[0] = "task1";
    dr[1] = "c1";
    dt22.Rows.Add(dr);
    
    DataRow dr2 = dt22.NewRow();
    dr2[0] = "test2";
    dr2[1] = "c2";
    dt22.Rows.Add(dr2);
    
    StringBuilder sb = new StringBuilder();
    
    IEnumerable<string> columnNames = dt22.Columns.Cast<DataColumn>().
                                      Select(column => column.ColumnName);
    sb.AppendLine(string.Join(",", columnNames));
    
    foreach (DataRow row in dt22.Rows)
    {
        IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
        sb.AppendLine(string.Join(",", fields));
    }
    
    File.WriteAllText(@"c:\Tasks.csv", sb.ToString());
    

    Prints:

    Tasks,AnotherColumn
    task1,c1
    test2,c2