Mike Wills
Mike Wills

Reputation: 21275

"The ConnectionString property is invalid." when I know it is valid

I have an ASP.NET MVC application where the database is on an IBM i-Series server. I have the application development close to completion when I started to get a The ConnectionString property is invalid. error popping up:

  1. only at log on
  2. after the first successful log on after rebuilding
  3. anyone logged on can still work normally

Also, note that this problem only shows up for one project in my solution. The other project uses the exact same connection string and doesn't have this problem (copied and pasted to be 100% sure). I am in active development on these projects, but have not touched the connections strings nor worked with the AccountController and related model classes after getting the login working.

I am using Visual Studio 2008 and .NET version 3.5.

Connection String:

<connectionStrings>
    <add name="IbmIConnectionString" connectionString="DataSource=192.168.50.200;DefaultCollection=QMFILES;Naming=sql;UserID=XXX;Password=XXXX;"/>
</connectionStrings>

Account Controller Logon method:

    [HttpPost]
    public ActionResult LogOn(LogOnModel model, string returnUrl)
    {
        string fullName = String.Empty;
        string employeeId = String.Empty;

        if (ModelState.IsValid)
        {
            if (MembershipService.ValidateUser(model.UserName, model.Password))
            {
                FormsService.SignIn(model.UserName, model.RememberMe);
                EmployeeLoginModel elm = new EmployeeLoginModel();
                elm.GetUserInfo(model.UserName, model.Password, out fullName, out employeeId);
                // Update the AuthCookie to include the last 4 digits of the SSN.
                string userDataString = String.Format("{0}|{1}|{2}", model.Password, fullName.Trim(), employeeId.Trim());
                HttpCookie authCookie = FormsAuthentication.GetAuthCookie(model.UserName, model.RememberMe);
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
                FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, userDataString);
                authCookie.Value = FormsAuthentication.Encrypt(newTicket);
                Response.Cookies.Add(authCookie);

                if (!String.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

Employee Login Model:

public class EmployeeLoginModel
{
    public string UserName { set; get; }
    public string Password { set; get; }

    private iDB2Connection conn;

    /// <summary>
    /// Initializes a new instance of the <see cref="EmployeeLoginModel"/> class.
    /// </summary>
    public EmployeeLoginModel()
    {
        conn = new iDB2Connection(ConfigurationManager.ConnectionStrings["IbmIConnectionString"].ConnectionString);
    }

    /// <summary>
    /// Determines whether [is valid user] [the specified username].
    /// </summary>
    /// <param name="username">The username.</param>
    /// <param name="password">The password.</param>
    /// <returns>
    ///     <c>true</c> if [is valid user] [the specified username]; otherwise, <c>false</c>.
    /// </returns>
    public bool IsValidUser(string username, string password)
    {
        int count = 0;

        // Get the data from the iSeries
        using (conn)
        {
            string sqlStatement = "SELECT COUNT(XXXXX) FROM XXXXX WHERE UPPER(XXXXXX) = @1 AND XXXXXX = @2";

            iDB2Command cmd = new iDB2Command(sqlStatement, conn);
            cmd.CommandType = CommandType.Text;
            cmd.Parameters.Add("@1", username.ToUpper());
            cmd.Parameters.Add("@2", password);
            conn.Open();
            count = (Int32)cmd.ExecuteScalar();
            conn.Close();
        }

        return ((count == 0) ? false : true);
    }

Upvotes: 3

Views: 10517

Answers (3)

Anytoe
Anytoe

Reputation: 1675

Another very trivial reason for getting this error is, that the required DB2 drivers are not installed.

The inner exception stated

Unable to load DLL 'cwbdc.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) Type: System.DllNotFoundException

Upvotes: 5

thangchung
thangchung

Reputation: 2030

I think because you use the connection outside the using statement, so it will be closed after go to other function, so when you call in IsValidUser, it will throw exception. in the second code, you use it in using statement, after call it will be Garbage Collection released. And it is work.

Upvotes: 1

Mike Wills
Mike Wills

Reputation: 21275

After posting this, I had a theory. I was switching between browsers getting things setup for a demo. I changed my method to:

    public bool IsValidUser(string username, string password)
    {
        int count = 0;

        // Get the data from the iSeries
        using (iDB2Connection conn = new iDB2Connection(ConfigurationManager.ConnectionStrings["IbmIConnectionString"].ConnectionString))
        {
            string sqlStatement = "SELECT COUNT(XXXXXX) FROM XXXXXX WHERE UPPER(XXXXXX) = @1 AND XXXXXX = @2";

            iDB2Command cmd = new iDB2Command(sqlStatement, conn);
            cmd.CommandType = CommandType.Text;
            cmd.Parameters.Add("@1", username.ToUpper());
            cmd.Parameters.Add("@2", password);
            conn.Open();
            count = (Int32)cmd.ExecuteScalar();
            conn.Close();
        }

        return ((count == 0) ? false : true);
    }

It seems to be working now. I wonder if that was the problem.

Upvotes: 2

Related Questions