0

我在 asp.net 中使用 SQL Server 2008 作为我的数据库。<a>在单击标签到 Web 表单时,我正在传递表名。那么,当我单击任何链接时,它如何根据收到的值更改其 sql 查询呢?

例如:

 <li class="last">
    <a href="category.aspx?cat=Architect&sub=Architects">Item 1.1</a>
 </li>

这里cat包含表名和sub条件名。

另一方面,我正在做:

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 Architect where subcategory3='" + s1 + "'",con);
      da.Fill(ds,"tab");
      dt = ds.Tables["tab"];
      DataGrid1.DataSource = dt;
      DataGrid1.DataBind();
   }
}

所以我只想给出Architect我只想通过的表名s- 我该怎么做?

4

4 回答 4

1

我建议您为此考虑其他解决方案,因为您当前所做的将导致非常简单的 SQL 注入,并且您的数据库将面临很大风险。我建议你有一个所有表的枚举,并在查询字符串中传递表的 id 而不是表名,并且在进行字符串连接之前,你应该确保条件字符串在任何 sql 注入中都是有效的

于 2012-07-04T10:53:09.920 回答
0
da = new SqlDataAdapter("select * from " + s + " where subcategory3='" + s1 + "'",con);
于 2012-07-04T10:51:55.340 回答
0

你的设计并不是最优的;是否可以考虑将所有数据存储在链接到类别和子类别的中央表中?

有几个弱点;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();
            }

        }
      }
   }
}

不过,我要说的一个评论是,即使你实现了上面的任何一个例子,你仍然有一个大问题;您的数据访问代码、业务逻辑和演示代码现在都被整合到此页面背后的代码中。您将不得不在需要的任何地方重复此操作,从而导致大量重复,这在您需要修复错误时尤其成问题。

相反,您可能会考虑创建类或使用ORM为您处理所有这些工作,因此您改为请求 Architect 对象列表,或来自类或组件的 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();
    }
 }

实际上,现在其他人的工作是担心如何获取对象并收集它们,从而大大减少了您在代码中的代码。此外,您可以轻松地在各种界面中重用它!

于 2012-07-04T11:41:58.560 回答
-1

像这样 ?

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();

            }



        }
于 2012-07-04T10:52:55.173 回答