基于不返回数据的 DatePicker 过滤 Web 窗体 GridView
Filtering Web Forms GridView based on DatePicker not returning data
我有一个带有 gridview 和两个日期选择器的 Web 表单以及一个用于提交具有日期时间约束的新查询的提交。作为过滤数据的开始和结束日期。在没有数据的情况下,数据加载正常,当单击具有所选日期的提交按钮时,没有任何反应。我想知道过滤后的数据是否未正确绑定(我是网络表单和 gridview 的新手。)
这是页面的隐藏代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindDataToGridView();
}
protected void dashboard_RowEditing(object sender, GridViewEditEventArgs e)
{
gridErrors.Text = string.Empty;
dashboard.EditIndex = e.NewEditIndex;
BindDataToGridView();
}
protected void dashboard_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
dashboard.EditIndex = -1;
BindDataToGridView();
}
protected void dashboard_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
dashboard.PageIndex = e.NewPageIndex;
BindDataToGridView();
}
protected void dashboard_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
gridErrors.Text = string.Empty;
GridViewRow tabRow = (GridViewRow)dashboard.Rows[e.RowIndex];
HiddenField hdnTabId = (HiddenField)tabRow.FindControl("hdnTabId");
TextBox TxtName = (TextBox)tabRow.Cells[1].Controls[0];
}
protected void button1_Click(object sender, EventArgs e)
{
var start = startDate.Text;
var startTime = DateTime.Parse(start);
var sqlStart = startTime.ToString("yyyy-MM-dd");
var end = endDate.Text;
var endTime = DateTime.Parse(end);
var sqlEnd = endTime.ToString("yyyy-MM-dd");
string sqlQuery = "SELECT TOP(100) TabID, TabName, Title, CreatedOnDate, TabPath From TableName " +
"where CreatedOnDate >= " + sqlStart + " and CreatedOnDate <= " + sqlEnd + " Order By TabName";
BindDataToGridView(sqlQuery);
}
public void BindDataToGridView(string sqlQuery =
"SELECT TOP(100) TabID, TabName, Title, CreatedOnDate, TabPath From TableName Order By TabName")
{
var connectionFromConfig = WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
using (SqlConnection db = new SqlConnection(connectionFromConfig))
{
try
{
db.Open();
SqlCommand command = new SqlCommand(sqlQuery, db);
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
if (dataSet.Tables[0].Rows.Count > 0)
{
dashboard.DataSource = dataSet;
dashboard.DataBind();
}
}
catch (SqlException ex)
{
gridErrors.Text = ex.Message;
}
finally
{
db.Close();
db.Dispose();
}
}
}
OnPageIndexChanging 方法
protected void dashboard_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
dashboard.PageIndex = e.NewPageIndex;
BindDataToGridView();
}
我需要在 Sql 服务器的 sqlStart 和 sqlEnd 变量前后添加单引号,以便将这些值与比较运算符一起使用。
好的,您找到了问题(缺少引号)。但是,归根结底?
是的,每个人都会蜂拥而至并注意“当”接受用户输入时,您不想连接到 sql(sql 注入的风险太高)。
但是,除非我们还为您提供了一个很好的设计方法,否则仅仅告诉您不要连接参数没有帮助。看看你的代码,你做了一个很棒的想法来拥有一个网格视图加载例程。而且您还想轻松地将 sql 传递给那个例程。然而,这个好主意 + 目标与使用强类型参数相冲突。
所以,让我们一箭双雕吧。
并发现使用参数通常是 LESS 代码,然后是一长串混乱的 sql 字符串,这很容易出错(这就是为什么你必须在这里 post)。
对于数字 - 没有引号,对于字符串 - 是,对于日期,也是。所以这是额外的开发人员工作量。那个又长又乱的字符串很难编写、调试和管理。
所以,我建议这个代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindDataToGridView();
}
void BindDataToGridView(SqlCommand cmdSQL = null)
{
// default sql
if (cmdSQL is null)
{
cmdSQL = new
SqlCommand("SELECT TabID, TabName, Title, CreatedOnDate, TabPath From TableName Order By TabName");
}
using (cmdSQL)
{
cmdSQL.Connection = new SqlConnection(conString);
cmdSQL.Connection.Open();
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
dashboard.DataSource = rst;
dashboard.DataBind();
}
}
注意几件事:
我们不必创建单独的连接对象 - sqlcommand 有一个!!
(并且由于我们没有创建单独的连接对象,因此处理 sql 命令会使用我们的 using 块来处理!!!
我们不需要单独的 datatable/dataset,也不需要数据适配器,我们也不需要 reader!! (sql 命令对象也有一个 reader!!!)。
所以,现在我们可以在没有参数的情况下调用我们的负载网格。
但是,对于当我们想要传递 sql 参数的情况?那么我们可以这样做:
{
string sqlQuery
= "SELECT TabID, TabName, Title, CreatedOnDate, TabPath From TableName " +
"WHERE CreatedOnDate >= @Start AND CreatedOnDate <= @End ORDER By TabName";
SqlCommand cmdSQL = new SqlCommand(sqlQuery);
cmdSQL.Parameters.Add("@Start", SqlDbType.Date).Value = startDate.Text;
cmdSQL.Parameters.Add("@End", SqlDbType.Date).Value = endDate.Text;
BindDataToGridView(cmdSQL);
}
所以,其实我们可以有参数,我们可以有更少的代码。我们可以轻松阅读 SQL,我们可以将 cmd SQL 传递给那个例程。
因此,这不仅是建议不要连接字符串,而且通过正确的方法,我们不必这样做,我们可以获得强大的数据类型转换和更少的代码,甚至更少的代码错误机会。
此外,检查 sql 服务器列是否为日期或日期时间。如果是日期时间,则在查询参数中指定该数据类型。
此外,您可以放弃 TOP 子句 - 只有在创建理论上不支持排序输出的 SQL 视图时才需要它。但对于原始 sql,则可以删除 TOP 子句。
我有一个带有 gridview 和两个日期选择器的 Web 表单以及一个用于提交具有日期时间约束的新查询的提交。作为过滤数据的开始和结束日期。在没有数据的情况下,数据加载正常,当单击具有所选日期的提交按钮时,没有任何反应。我想知道过滤后的数据是否未正确绑定(我是网络表单和 gridview 的新手。) 这是页面的隐藏代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindDataToGridView();
}
protected void dashboard_RowEditing(object sender, GridViewEditEventArgs e)
{
gridErrors.Text = string.Empty;
dashboard.EditIndex = e.NewEditIndex;
BindDataToGridView();
}
protected void dashboard_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
dashboard.EditIndex = -1;
BindDataToGridView();
}
protected void dashboard_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
dashboard.PageIndex = e.NewPageIndex;
BindDataToGridView();
}
protected void dashboard_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
gridErrors.Text = string.Empty;
GridViewRow tabRow = (GridViewRow)dashboard.Rows[e.RowIndex];
HiddenField hdnTabId = (HiddenField)tabRow.FindControl("hdnTabId");
TextBox TxtName = (TextBox)tabRow.Cells[1].Controls[0];
}
protected void button1_Click(object sender, EventArgs e)
{
var start = startDate.Text;
var startTime = DateTime.Parse(start);
var sqlStart = startTime.ToString("yyyy-MM-dd");
var end = endDate.Text;
var endTime = DateTime.Parse(end);
var sqlEnd = endTime.ToString("yyyy-MM-dd");
string sqlQuery = "SELECT TOP(100) TabID, TabName, Title, CreatedOnDate, TabPath From TableName " +
"where CreatedOnDate >= " + sqlStart + " and CreatedOnDate <= " + sqlEnd + " Order By TabName";
BindDataToGridView(sqlQuery);
}
public void BindDataToGridView(string sqlQuery =
"SELECT TOP(100) TabID, TabName, Title, CreatedOnDate, TabPath From TableName Order By TabName")
{
var connectionFromConfig = WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
using (SqlConnection db = new SqlConnection(connectionFromConfig))
{
try
{
db.Open();
SqlCommand command = new SqlCommand(sqlQuery, db);
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
if (dataSet.Tables[0].Rows.Count > 0)
{
dashboard.DataSource = dataSet;
dashboard.DataBind();
}
}
catch (SqlException ex)
{
gridErrors.Text = ex.Message;
}
finally
{
db.Close();
db.Dispose();
}
}
}
OnPageIndexChanging 方法
protected void dashboard_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
dashboard.PageIndex = e.NewPageIndex;
BindDataToGridView();
}
我需要在 Sql 服务器的 sqlStart 和 sqlEnd 变量前后添加单引号,以便将这些值与比较运算符一起使用。
好的,您找到了问题(缺少引号)。但是,归根结底? 是的,每个人都会蜂拥而至并注意“当”接受用户输入时,您不想连接到 sql(sql 注入的风险太高)。
但是,除非我们还为您提供了一个很好的设计方法,否则仅仅告诉您不要连接参数没有帮助。看看你的代码,你做了一个很棒的想法来拥有一个网格视图加载例程。而且您还想轻松地将 sql 传递给那个例程。然而,这个好主意 + 目标与使用强类型参数相冲突。
所以,让我们一箭双雕吧。
并发现使用参数通常是 LESS 代码,然后是一长串混乱的 sql 字符串,这很容易出错(这就是为什么你必须在这里 post)。
对于数字 - 没有引号,对于字符串 - 是,对于日期,也是。所以这是额外的开发人员工作量。那个又长又乱的字符串很难编写、调试和管理。
所以,我建议这个代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindDataToGridView();
}
void BindDataToGridView(SqlCommand cmdSQL = null)
{
// default sql
if (cmdSQL is null)
{
cmdSQL = new
SqlCommand("SELECT TabID, TabName, Title, CreatedOnDate, TabPath From TableName Order By TabName");
}
using (cmdSQL)
{
cmdSQL.Connection = new SqlConnection(conString);
cmdSQL.Connection.Open();
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
dashboard.DataSource = rst;
dashboard.DataBind();
}
}
注意几件事: 我们不必创建单独的连接对象 - sqlcommand 有一个!! (并且由于我们没有创建单独的连接对象,因此处理 sql 命令会使用我们的 using 块来处理!!!
我们不需要单独的 datatable/dataset,也不需要数据适配器,我们也不需要 reader!! (sql 命令对象也有一个 reader!!!)。
所以,现在我们可以在没有参数的情况下调用我们的负载网格。
但是,对于当我们想要传递 sql 参数的情况?那么我们可以这样做:
{
string sqlQuery
= "SELECT TabID, TabName, Title, CreatedOnDate, TabPath From TableName " +
"WHERE CreatedOnDate >= @Start AND CreatedOnDate <= @End ORDER By TabName";
SqlCommand cmdSQL = new SqlCommand(sqlQuery);
cmdSQL.Parameters.Add("@Start", SqlDbType.Date).Value = startDate.Text;
cmdSQL.Parameters.Add("@End", SqlDbType.Date).Value = endDate.Text;
BindDataToGridView(cmdSQL);
}
所以,其实我们可以有参数,我们可以有更少的代码。我们可以轻松阅读 SQL,我们可以将 cmd SQL 传递给那个例程。
因此,这不仅是建议不要连接字符串,而且通过正确的方法,我们不必这样做,我们可以获得强大的数据类型转换和更少的代码,甚至更少的代码错误机会。
此外,检查 sql 服务器列是否为日期或日期时间。如果是日期时间,则在查询参数中指定该数据类型。
此外,您可以放弃 TOP 子句 - 只有在创建理论上不支持排序输出的 SQL 视图时才需要它。但对于原始 sql,则可以删除 TOP 子句。