2010-11-30 4 views
1

J'ai une application ASP.NET MVC où la base de données est sur un serveur IBM i-Series. J'ai le développement d'applications d'achèvement quand j'ai commencé à obtenir une erreur The ConnectionString property is invalid. apparaître:"La propriété ConnectionString n'est pas valide." quand je sais que c'est valide

  1. uniquement lors de la connexion sur
  2. après la première connexion réussie sur après la reconstruction
  3. quelqu'un connecté peut encore fonctionner normalement

Notez également que ce problème n'apparaît que pour un projet dans ma solution. L'autre projet utilise exactement la même chaîne de connexion et n'a pas ce problème (copié et collé pour être sûr à 100%). Je suis en développement actif sur ces projets, mais je n'ai pas touché les chaînes de connexion, ni travaillé avec les classes AccountController et les classes de modèles associées après avoir obtenu le login. Je utilise Visual Studio 2008 et .NET version 3.5.

Chaîne de connexion:

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

contrôleur compte méthode de connexion:

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

Connexion Employé Modèle:

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); 
    } 
+1

Plus de détails? Peut-être la chaîne de connexion, comment vous récupérez la chaîne de connexion, à quoi ressemble votre contrôleur de compte? Postez vos logs SVN aussi, je ne crois plus jamais "je n'y ai plus touché". ;) – jfar

+1

BTW voulez-vous vraiment que votre mot de passe soit listé ici? Si c'est votre vrai mot de passe, je vous suggère de le changer immédiatement ... (Le fait d'éditer votre article ici n'aidera pas car les gens peuvent voir l'historique des modifications.) – Eilon

+0

Je n'ai pas de journaux SVN car il n'est pas sous contrôle de version encore. –

Répondre

2

Après avoir enregistré, j'avais une théorie. Je passais d'un navigateur à l'autre pour que les choses soient configurées pour une démo. J'ai changé ma méthode pour:

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

Cela semble fonctionner maintenant. Je me demande si c'était le problème.

+3

Oh Dieu inline SQL? – jfar

+2

@jfar, quel est le problème avec SQL inline?Cela me semble correct, il utilise même des paramètres pour éviter l'injection SQL, donc c'est un code parfaitement valide. –

+0

@Darin: Paramètres: bien. Inline Sql: mauvais. Le problème est dans la découverte des problèmes dans le cas d'un changement de modèle de données. Disons qu'ils renomment l'un des noms de domaine, ce qui est généralement plus commun que les gens pensent. La seule façon de découvrir cela est un problème si la méthode particulière qui sélectionne sur ce nom de champ est appelée. Ce qui signifie, c'est une erreur d'exécution. – NotMe

1

Je pense que parce que vous utilisez la connexion en dehors de l'instruction using, elle sera donc fermée après aller à une autre fonction, donc quand vous appelez dans IsValidUser, elle va lever une exception. dans le deuxième code, vous l'utilisez dans l'utilisation de la déclaration, après l'appel sera libéré Garbage Collection. Et c'est du travail.

1

Une autre raison très triviale pour obtenir cette erreur est que les pilotes DB2 requis ne sont pas installés.

L'exception intérieure a déclaré

Impossible de charger 'cwbdc.dll' DLL: Le module spécifié est introuvable. (Exception de HRESULT: 0x8007007E) Type: System.DllNotFoundException