C# 如何在ASP中传递SQL连接中修改的表名
我正在使用SQL Server 2008作为asp.net中的数据库。在单击C# 如何在ASP中传递SQL连接中修改的表名,c#,asp.net,.net,sql-server-2008,sql-server-2008-r2,C#,Asp.net,.net,Sql Server 2008,Sql Server 2008 R2,我正在使用SQL Server 2008作为asp.net中的数据库。在单击标记到web表单时,我正在传递表名。那么,当我单击任何链接时,它如何根据收到的值更改其sql查询呢 例如: <li class="last"> <a href="category.aspx?cat=Architect&sub=Architects">Item 1.1</a> </li> 因此,我只想给出表名Architect,我只想传递s——我该怎么做
标记到web表单时,我正在传递表名。那么,当我单击任何链接时,它如何根据收到的值更改其sql查询呢
例如:
<li class="last">
<a href="category.aspx?cat=Architect&sub=Architects">Item 1.1</a>
</li>
因此,我只想给出表名Architect
,我只想传递s
——我该怎么做 像这样
da = new SqlDataAdapter("select * from " + s + " where subcategory3='" + s1 + "'",con);
SqlConnection con=new SqlConnection("Data Source=ANURAG-PC;Initial Catalog=dbPortal;Persist Security Info=True;User ID=sa;Password=anurag");
SqlDataAdapter da;
DataSet ds=new DataSet();
static DataTable dt=new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
string s = Request.QueryString["cat"];
string s1 = Request.QueryString["sub"];
da = new SqlDataAdapter("select * from '"+s+"' where subcategory3='" + s1 + "'",con);
da.Fill(ds);
dt = ds.Tables[0];
DataGrid1.DataSource = dt;
DataGrid1.DataBind();
}
}
我建议您考虑其他解决方案,因为您当前所做的将导致非常简单的SQL注入,并且您的数据库将面临巨大的风险。我建议您拥有一个所有表的枚举,并在查询字符串中传递表的id,而不是表名,而且在进行字符串浓缩之前,您还应该确保条件字符串在任何sql注入中都是有效的;是否可以考虑将所有数据存储在链接到类别和子类别?的中心表中? 有几个弱点;sql的任何字符串串联都会使您面临SqlInjection攻击。例如,即使您从下拉列表中选择值,客户端脚本仍有可能修改组合框中的值,或者攻击者只需将数据发布到服务器端事件处理程序 此外,必须从多个表中获取数据意味着您可能必须在结果中处理不同的模式;如果您预期会出现这种情况(即某些表的列数比其他表的多),那么您可以适当地处理它 然后,您的查询将类似于:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
string s = Request.QueryString["cat"];
string s1 = Request.QueryString["sub"];
if(String.IsNullOrEmpty(s) || String.IsNullOrEmpty(s1)) { return; } //Improve Validation and error reporting
using(SqlConnection conn = new SqlConnection("Data Source=ANURAG-PC;Initial Catalog=dbPortal;Persist Security Info=True;User ID=sa;Password=anurag"))
{
using(SqlCommand command = new SqlCommand(conn))
{
command.CommandType = CommandType.Text;
command.CommandText = "SELECT * FROM Table WHERE Category = @Category AND SubCategory = @SubCategory";
command.Parameters.Add(new SqlParameter() { Type = SqlDbType.String, Name = "@Category", Value = s });
command.Parameters.Add(new SqlParameter() { Type = SqlDbType.String, Name = "@SubCategory", Value = s1 });
conn.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
DataTable data = new DataTable("MyData");
data.Load(reader);
DataGrid1.DataSource = data;
DataGrid1.DataBind();
}
}
}
}
}
如果坚持使用原始模型,则可能需要将表名列入白名单,以便继续使用参数化查询:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
string s = Request.QueryString["cat"];
string s1 = Request.QueryString["sub"];
if(String.IsNullOrEmpty(s) || String.IsNullOrEmpty(s1)) { return; } //Improve Validation and error reporting
using(SqlConnection conn = new SqlConnection("Data Source=ANURAG-PC;Initial Catalog=dbPortal;Persist Security Info=True;User ID=sa;Password=anurag"))
{
using(SqlCommand command = new SqlCommand(conn))
{
command.CommandType = CommandType.Text;
switch(s)
{
case "Architect":
command.CommandText = "SELECT * FROM Architect WHERE SubCategory = @SubCategory";
break;
case "SomethingElse":
command.CommandText = "SELECT * FROM SomethingElse WHERE SubCategory = @SubCategory";
break;
default:
return; //Again, improve error handling
}
command.Parameters.Add(new SqlParameter() { Type = SqlDbType.String, Name = "@SubCategory", Value = s1 });
conn.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
DataTable data = new DataTable("MyData");
data.Load(reader);
DataGrid1.DataSource = data;
DataGrid1.DataBind();
}
}
}
}
}
但我要说的一点是,即使你实现了上面的任何一个例子,你仍然有一个大问题;您的数据访问代码、业务逻辑和表示代码现在都已包含在此页面的代码中。您必须在任何需要的地方重复此操作,从而导致大量重复,这在您需要修复bug时尤其是一个问题
相反,您可以使用或使用来为您处理所有这些工作,因此您可以从类或组件请求一个架构师对象列表,或一个SomethingElse列表,从而让aspx来处理表示。还有一个关于为什么您可能不想使用ORM的问题
如果遵循此路线,您的代码可能会变成:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
string s = Request.QueryString["cat"];
string s1 = Request.QueryString["sub"];
//Still do validation on s and s1
ObjectFactory of = new ObjjectFactory();
DataGrid1.DataSource = ObjectFactory.GetObjects(s, s1);
DataGrid1.DataBind();
}
}
实际上,现在其他人的工作就是担心如何获取和收集对象,从而大大减少代码中的代码。此外,您还可以轻松地跨多种接口重用它 这里要非常小心,您使用的是易受SQL注入攻击的动态SQL。至少,参数化您的查询!有多少张桌子?也就是说,有多少个类别?@Ravi:其他人也这样做,也投他们的反对票;这是jst的查询解决方案,同样在querystring中发送表名也不是一个好主意。我只是对你投了反对票,因为我看到你的帖子中有易受攻击的代码。。这不是关于否决票,而是关于练习,建议否决别人不是一种运动态度。
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
string s = Request.QueryString["cat"];
string s1 = Request.QueryString["sub"];
//Still do validation on s and s1
ObjectFactory of = new ObjjectFactory();
DataGrid1.DataSource = ObjectFactory.GetObjects(s, s1);
DataGrid1.DataBind();
}
}