-1

This is my code which runs perfectly fine in my local, but when I deployed it on iis it gives IndexOutOfRangeException.

The error is this: System.IndexOutOfRangeException: There is no row at position 0.
Please help.
Thanks in advance.

 private void showdetail(object sender, EventArgs e)
 {
     SqlConnection con = new SqlConnection(ConnectionString);
     con.Open();
     str = "query";
     cmd = new SqlCommand(str, con);
     SqlDataAdapter da = new SqlDataAdapter(cmd);
     DataSet ds = new DataSet();
     da.Fill(ds);
     if(ds.Tables[0].Rows.Count > 0) { 
         lbl_fname.Text = ds.Tables[0].Rows[0]["a"].ToString(); //gives error here
         Lbl_lname.Text = ds.Tables[0].Rows[0]["b"].ToString();
         lbl_add1.Text = ds.Tables[0].Rows[0]["c"].ToString();
         lbl_add2.Text = ds.Tables[0].Rows[0]["d"].ToString();
         lbl_city.Text = ds.Tables[0].Rows[0]["e"].ToString();
         lbl_state.Text = ds.Tables[0].Rows[0]["f"].ToString();
         lbl_county.Text = ds.Tables[0].Rows[0]["g"].ToString();
         lbl_country.Text = ds.Tables[0].Rows[0]["h"].ToString();
         lbl_taxid.Text = ds.Tables[0].Rows[0]["i"].ToString();
         lbl_email.Text = ds.Tables[0].Rows[0]["j"].ToString();
         lbl_phone1.Text = ds.Tables[0].Rows[0]["k"].ToString();
         lbl_phone2.Text = ds.Tables[0].Rows[0]["l"].ToString();
         con.Close();
     }
     else
     {
         ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "alertMessage", "alert('No Data found.')", true);
     }
}
computercarguy
  • 2,173
  • 1
  • 13
  • 27
maleficent
  • 53
  • 1
  • 7
  • Which line is it giving the error on? – computercarguy Jan 29 '20 at 21:49
  • 4
    Please read [ask] and share your research. Your `ConnectionString` probably points to a different database, which has no records for your "query". – CodeCaster Jan 29 '20 at 21:49
  • @CodeCaster - ConnectionString doesn't point to a different database, because the same code works in my local. – maleficent Jan 29 '20 at 21:51
  • @ computercarguy - I edited my question – maleficent Jan 29 '20 at 21:52
  • 1
    It's literally the only thing that can differ between both environments. Well apart from them being entirely different machines, but alas. So either you aren't showing the actual code that runs (and I can see you aren't), or there's something else going on, but either way you're not showing us enough information (and again, read [ask]) to troubleshoot this for you. – CodeCaster Jan 29 '20 at 21:55
  • 1
    Honestly I don't see how that line would throw that particular error if it's actually getting passed that `if` statement... Either I'm misreading this or something goofy is going on. – Code Stranger Jan 29 '20 at 21:59
  • Check your column count in the data table – Black Frog Jan 29 '20 at 22:00
  • This is a good example of why Entity, or at least Dapper, can improve coding ease of use and error protection/recognition. – computercarguy Jan 29 '20 at 22:02
  • If you add in `if(ds.Tables.Count > 0) {` before your row check and assign `ds.Tables[0].Rows[0]` to a helper variable within the current `if` statement, do you still get the error? – computercarguy Jan 29 '20 at 22:04

1 Answers1

0

Since the OP seems to have quit responding to the comments, I'm going to assume either my comment fixed the issue, brought out what was really the issue, or another comment (that I'll include here) fixed the problem.

Error checking

My suggestion is to do basic error checking on the Table as well as the Rows. You need to make sure that the query returned something useful, or your Table could be null or, at best, empty. Adding another check before the Rows.Count check can help prevent IndexOutOfRangeException errors when Table is empty.

if (ds.Tables.Count > 0) {
    if (ds.Tables[0].Rows.Count > 0) { 
        DataRow row = ds.Tables[0].Rows[0];
        lbl_fname.Text = row["a"].ToString();

This check can be done in a single if statement, but I'm leaving it as 2 for clarity. Also, replacing Count with Any can be a performance improvement, although that might require the Linq library.

Using a helper variable like row can help determine just exactly where the error is happening since the original code uses 2 new indexes ([0] and ["a"]) for the first time on a single line, so the error could be with either index. Also, using a variable here should help clean up the code to make it easier to read as well as potentially making it run a bit faster. Sure, the compiler may introduce this shortcut on its own, but I never rely on that.

ConnectionString

Then there's the suggestion by CodeCaster that the ConnectionString could be different between the local and the deployed versions. I've worked with codebases that have it set up to get a different connection string depending on the compile option (Debug vs Release).

Also, depending on how this project is deployed, it may not copy the file over correctly that contains the connection string, so it may have a Production app.config the file that is different than the one used locally. It could also be that the OP accidentally didn't check in a change to the app.config so an automatic deployment wouldn't update that file.

Other suggestions

Using Entity or Dapper can deal with putting data into an object for you, so it's easier to handle. It can also be easier to do error checking and handling, especially when your query doesn't return values. They can take time to set up, but they can also be really useful. They also tend to clean up code considerably, too.

You can also include a using in front of the SqlConnection so it'll automatically close the connection, even when an exception is thrown. You'll then be able to leave out explicitly closing it. You can do the same with SqlDataAdapter. It also wouldn't hurt to put in some try ... catch blocks to prevent your app from crashing uncontrollably and without getting good error feedback.

The C# using statement, SQL, and SqlConnection

SqlDataAdapter with using keyword

Community
  • 1
  • 1
computercarguy
  • 2,173
  • 1
  • 13
  • 27