2012-10-09 4 views
2

Je suis coincé avec un problème et n'ai pas une seule idée WTF se passe. J'ai une application web C# qui doit communiquer avec une base de données MySQL en utilisant des services web. Je peux utiliser des méthodes pour insérer des données, mais chaque fois que j'essaie de lire quoi que ce soit (ExecuteReader ou ExecuteScalar), il échoue avec ce message très étrange:ASP .Net - MySql - Impossible de lire les données

La clé donnée était présent dans le dictionnaire.

Maintenant, le service Web utilise cette classe pour communiquer avec le db:

public class DatabaseHelper 
{ 
    private MySqlCommand cmd; 
    private MySqlConnection con; 
    public DatabaseHelper() 
    { 
     String server = "localhost"; 
     String database = "testdb"; 
     String password = "password"; 
     String username = "root"; 


     String connString = "Server = " + server + "; Database = " + database + "; Uid = " + username + "; Pwd = " + password + "; default command timeout=60;"; 
     con = new MySqlConnection(); 
     con.ConnectionString = connString; 

     cmd = new MySqlCommand(); 

     cmd.Connection = con; 
    } 

    public void RunExecuteNonQuery(string sql, MySqlParameter[] param) 
    { 
     try 
     { 

      cmd.CommandText = sql; 
      if (param != null) 
      { 
       cmd.Parameters.AddRange(param); 
      } 
      cmd.CommandText = sql; 
      con.Open(); 
      cmd.ExecuteNonQuery(); 
      con.Close(); 
      cmd.Parameters.Clear(); 

     } 
     catch (MySqlException ex) 
     { 
      con.Close(); 

     } 
    } 
    public object RunExecuteScalar(string sql, MySqlParameter[] param) 
    { 
     if (param != null) 
     { 
      cmd.Parameters.AddRange(param); 
     } 
     cmd.CommandText = sql; 
     object ret; 
     con.Open(); 
     ret = cmd.ExecuteScalar(); 
     con.Close(); 
     cmd.Parameters.Clear(); 
     return ret; 
    } 

    public MySqlDataReader RunExecuteDataReader(string sql, MySqlParameter[] param) 
    { 
     if (param != null) 
     { 
      cmd.Parameters.AddRange(param); 
     } 
     cmd.CommandText = sql; 
     MySqlDataReader ret = null; 

     con.Open(); 

     ret = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection); 
     cmd.Parameters.Clear(); 


     return ret; 
    } 
} 

Il échoue sur cmd.ExecuteReader ou cmd.ExecuteScalar!

D'autre part, une méthode du service Web se présente comme suit:

[WebMethod] 
    public string[] GetCategories() 
    { 
     String sql = "SELECT * FROM category"; 
     DatabaseHelper dh = new DatabaseHelper(); 
     MySqlDataReader dr = dh.RunExecuteDataReader(sql, null); 
     List<String> categories = new List<string>(); 
     while (dr.Read()) 
     { 
      categories.Add(dr[0].ToString()); 
     } 
     dr.Close(); 

     return categories.ToArray(); 
    } 

Il est vraiment étrange puisque l'erreur est très cryptique (je ne suis pas en utilisant un dictionnaire du tout) et je l'ai utilisé cette même classe dans de nombreuses autres applications. J'ai essayé cette même solution sur un autre ordinateur avec le même résultat. J'ai même essayé différentes versions de MySql.Data.dll

La pile d'erreur:

System.Collections.Generic.KeyNotFoundException était non gérée par le code utilisateur HResult = -2146232969 message = La clé donnée était pas présent dans le dictionnaire. Source = mscorlib StackTrace: à System.Collections.Generic.Dictionary`2.get_Item (touche TKey) à MySql.Data.MySqlClient.CharSetMap.GetChararcterSet (version DBVersion, String CharSetName) à MySql.Data.MySqlClient.NativeDriver. GetFieldMetaData41() à MySql.Data.MySqlClient.NativeDriver.GetFieldMetaData() à MySql.Data.MySqlClient.NativeDriver.ReadColumnMetadata (nombre Int32) à MySql.Data.MySqlClient.MySqlDataReader.NextResult() à MySql.Data. MySqlClient.MySqlCommand.ExecuteReader (CommandBehavior comportement ) à Panopticon.DataLayer.DatabaseHelper.RunExecuteDataReader (String sql, MySqlParameter [] param) dans C: \ Users \ Visar \ Documents \ Visual studio 2010 \ Projects \ TestApp \ TestApp \ DataLayer \ DatabaseHelper.cs: ligne 84 à Panopticon._Default.Page_Load (Expéditeur d'objet, EventArgs e) dans C: \ Utilisateurs \ Visar \ Documents \ Visual Studio 2010 \ Projects \ TestApp \ TestApp \ Default.aspx.cs: ligne 16 à System.Web.Util.CalliEventHandlerDelegateProxy.Callback (de l'expéditeur de l'objet, EventArgs e) à System.Web.UI.Control.OnLoad (EventArgs e) à System.Web. UI.Control.LoadRecursive() à System.Web.UI.Page.ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException:

+0

serait factoriser votre aide et de lire un fichier .config et sortir des valeurs .. hardcoded – MethodMan

+0

Pourriez-vous poster la pile d'erreur plz – Marc

+0

je lis bien sûr web.config penser qu'il y avait le problème :( – user10901

Répondre

1

Remplacer avec ce code - vous pouvez supprimer AddRange méthode

cmd.Parameters.Add(param); 

Et ajouter un traitement foreach

foreach (var p in param) 
     { 
      cmd.Parameters.Add(p); 
     } 

les meilleures pratiques comme mentionné avec DJ KRAZE, est d'utiliser AddWithValue method

Lien: http://msdn.microsoft.com/fr-fr/library/system.data.sqlclient.sqlparametercollection.addwithvalue.aspx

+0

ou cmd.Parameters.AddWithValues ​​(param) la méthode .Add a été dépréciée btw – MethodMan

+0

oui je sais mais la première fois est de trouver le problème, et la deuxième fois de répondre avec AddWithValue, merci DJ KRAZE pour remarque, j'ajoute ta réponse à ma réponse –

+0

pas un problème Aghilas votre réponse est assez bonne +1 Je vous ai donné l'autre problème que j'ai remarqué est qu'il passe Params comme un tableau .. qui pourrait également lui causer des problèmes potentiels si l'un des params n'est pas rempli ou est nul votre solution devrait suffire à le faire marcher – MethodMan

Questions connexes