I've written some basic code in ASP.NET that accesses a Microsoft Access database, which works when I run in debug mode on IIS Express, but when I published the application and tried to run on the actual website, I get the error.
[IndexOutOfRangeException: There is no row at position 0.]
System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex) +2430497
NIM_Tool.Default.Page_Load(Object sender, EventArgs e) +2321
System.Web.UI.Control.OnLoad(EventArgs e) +106
System.Web.UI.Control.LoadRecursive() +68
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3785
From modifying some of my code, I'm pretty confident that the database is unable to be found, but I can't figure out why it's able to be accessed in debug/release mode but not from the published mode. After clicking publish, all files went to the bin/Release/Publish/ folder from the root directory, which I then copied all the children of the Publish folder to the correct server path. The children files/folder also contained the correct MS Access database.
code from the DataLayer.cs file
public class DataLayer {
static OleDbConnection conn;
static OleDbCommand cmd;
static String connString;
static OleDbDataAdapter adp;
private static void CreateCommand()
{
// have also tried hardcoding this to the production server path but this failed too
connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Server.MapPath("MyDatabase.mdb") + ";Persist Security Info=False;"
conn = new OleDbConnection(connString);
cmd = new OleDbCommand();
cmd.Connection = conn;
adp = new OleDbDataAdapter();
}
public static DataTable GetDefaultDeposit()
{
DataTable dt = new DataTable();
CreateCommand();
try {
cmd.CommandText = "SELECT * FROM Table1";
adp.SelectCommand = cmd;
adp.Fill(dt);
}
catch (Exception ex) {
}
return dt;
}
}
And The Default.aspx.cs code
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataTable dtDeposit = DataLayer.GetDefaultDeposit();
string fixedCost = (string)dtDeposit.Rows[0]["FixedCost"];
}
}
The MyDatabase.mdb file is located in the same directory as the DataLayer.cs file. I've tried hardcoding the database path as well to where it should be accessed on the server, but got the same error message as well.
A little advice: you are being your own enemy when you catch an error and don't do anything with it. It is called "swallowing an error" and it hides root-causes.
Instead, I would recommend doing a re-throw. Put your (original) Exception as the .InnerException
. You might want to have your connString
in the .Description for the (outer) Exception
. (Just in case MapPath didn't do what you thought it should, etc.)
Like this:
public static DataTable GetDefaultDeposit()
{
DataTable dt = new DataTable();
CreateCommand();
try {
cmd.CommandText = "SELECT * FROM Table1";
adp.SelectCommand = cmd;
adp.Fill(dt);
}
catch (Exception ex) {
throw new Exception("ConnString=" + connString, ex);
}
return dt;
}