0

I'm using SQL Server 2008 as my database in asp.net. And I'm passing the table name while at the time of clicking the <a> tag to web form. So how can I achieve this thing that when I click any link it change its sql query according to the value it receive?

For example:

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

Here cat contains the table name and sub contains the condition name.

And at the other side I'm doing:

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

So I just want that insted of giving table name Architect I just want to pass s - how can I do that?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Anurag Mittal
  • 39
  • 3
  • 11
  • 1
    Be very careful here, you are using dynamic SQL which is vulnerable to SQL injection. At the very least, parameterize your queries! – Simon Jul 04 '12 at 10:51
  • How many tables are there - i.e. how many categories are there? – dash Jul 04 '12 at 11:32

4 Answers4

1

I would suggest that you think of other solution for this because what you are currently doing will lead to a very simple SQL Injection and your database will be at a great risk. I suggest that you have an enum of all tables and pass the id of the table in the query string instead of the table name and also you should make sure that the condition string is valid from any sql injection before making the string concatination

Samir Adel
  • 2,691
  • 2
  • 15
  • 16
0
da = new SqlDataAdapter("select * from " + s + " where subcategory3='" + s1 + "'",con);
Asif Mushtaq
  • 13,010
  • 3
  • 33
  • 42
0

Your design isn't really optimal; is it possible to consider storing all data in a central table linked to both Category and SubCategory?

There are several weaknesses; any string concatenation of sql leaves you open to SqlInjection attacks. Even if you are choosing values from drop down lists, for example, it is still possible for client side script to modify the values in your combo boxes, or for an attacker to simply post data to your server side event handler.

In addition, having to source data from several tables means that you may have to deal with different schemas in your results; if you expect this (i.e. some tables will have more columns than others) then you can handle it appropriately.

Your query would then become something similar to:

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

        }
      }
   }
}

If you are stuck with your original model, then you may want to whitelist the table names so you can stick with parameterised queries:

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

        }
      }
   }
}

One comment I would make though, is that even if you implement either of the examples above, you still have a big problem; your data access code, business logic, and presentation code are all now munged into the code behind for this page. You will have to repeat this everywhere you need it leading to plenty of duplication, which is especially a problem when you need to fix bugs.

Instead, you might consider creating classes or using an ORM to handle all of this work for you, so you instead request a list of Architect objects, or a list of SomethingElse from a class or component, thus leaving the aspx to deal with the presentation. There is also a discussion here about why you might not want to use an ORM.

If you follow this route, your code might then become something like:

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

Effectively, it is now someone else's job to worry about how to get the objects, and to collect them, vastly reducing the code you have in your code behind. Plus you can easily reuse that across a wide variety of interfaces!

Community
  • 1
  • 1
dash
  • 89,546
  • 4
  • 51
  • 71
-1

Like this ?

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

            }



        }
Satinder singh
  • 10,100
  • 16
  • 60
  • 102
  • @Ravi: others also did the same, do downvote for them too; this is jst the solution for his query, Aslo sending table name in querystring is also not a good idea – Satinder singh Jul 04 '12 at 11:49
  • i just downvote for you because, i saw your post with code which vulnerable.. its not about the downvote, its about the practise, and suggesting to downvote other is not a sportive attitude. – Ravi Gadag Jul 04 '12 at 12:06