I am trying to use StringBuilder to create a string that will be used as the innerHtml of a div. My current code works but when I refresh the page the amount of data I have doubles so that everything shows twice, why is this? My current code is as follows:
protected void refreshUpcomingMaintenance()
{
StringBuilder sb = new StringBuilder();
sb.Append("<h2>Upcoming Maintenance</h2>");
foreach (DataRow row in dt.Rows)
{
if (row["Status"].ToString() != null
&& row["Status"].ToString() == "A "
&& (row["Type"].ToString() == "Planned Outage")
&& (DateTime.Now < DateTime.Parse(row["StartTime"].ToString())))
{
sb.Append("<p>NEW UPCOMING EVENT</p>");
sb.Append("<p>" + (row["SubjectLine"].ToString()) + "</p>");
}
}
upcomingMaintenanceHolder.InnerHtml = sb.ToString();
}
So when the page first loads everything works fine and the two events that should be showing are appended to the sb (StringBuilder) and I set the innerHtml on my div to that StringBuilder value to string. But, the problem is when I click refresh on the page instead of showing two events my screen now shows 4.
I did some debugging and every time I refresh the page the count of dt.Rows has doubled, which is why this is happening but why is the count of dt.Rows doubling every time? The amount of rows in my actual SQL database does not change only the count at this point in the code (The rows don't duplicate in SQL only in this instance). Thanks for the help.
Also, for reference, this is how dt is being filled:
private static string strSQLConn = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString;
private static SqlConnection sqlConn = new SqlConnection(strSQLConn);
private static DataTable dt = new DataTable();
private static SqlCommand command = new SqlCommand("getNetEvents", sqlConn);
protected void Page_Load(object sender, EventArgs e)
{
headerDate.InnerText = DateTime.Now.ToString();
command.CommandType = CommandType.StoredProcedure;
sqlConn.Open();
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(dt);
this.refreshStatus();
refreshUpcomingMaintenance();
sqlConn.Close();
}
It is because you have defined the dt
as static
and it's same copy is being maintained in your application and reused. A quick dirty fix is clearing the rows at page load before populating it again:
protected void Page_Load(object sender, EventArgs e)
{
dt.Rows.Clear();
..... // your previous code
}
But that is not a recommended way to use static
fields at page level in a web application as same copy is shared across the application and every user will be seeing same data which of-course you don't want. Every user or client should be seeing his copy of data.
The better approach is to make them non-static so that every time a new object gets created.
What you can do is create a class that does the database interaction for providing you the connection, reader etc and re-use in the pages. Just to show you an example you can create a method which will return the DataTable
instance back:
protected void Page_Load(object sender, EventArgs e)
{
headerDate.InnerText = DateTime.Now.ToString();
DataTable dt = GetData();
// now use it as needed
}
private DataTable GetData()
{
string strSQLConn = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString;
SqlConnection sqlConn = new SqlConnection(strSQLConn);
DataTable dt = new DataTable();
SqlCommand command = new SqlCommand("getNetEvents", sqlConn);
command.CommandType = CommandType.StoredProcedure;
sqlConn.Open();
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(dt);
sqlConn.Close();
return dt;
}