L’index était en dehors des limites de l’exception de tableau

Voici mon code pour obtenir des données à partir d’un fichier plat et les insérer dans SQL Server. Il génère une exception ( Index was outside the bounds of the array ).

 ssortingng path = ssortingng.Concat(Server.MapPath("~/TempFiles/"), Fileupload1.FileName); ssortingng text = System.IO.File.ReadAllText(path); ssortingng[] lines = text.Split(' '); con.Open(); SqlCommand cmd = new SqlCommand(); ssortingng[] Values = new ssortingng[3]; foreach (ssortingng line1 in lines) { Values = line1.Split(';'); ssortingng query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')"; cmd = new SqlCommand(query,con); cmd.ExecuteNonQuery(); } 

L’exception se produit car l’ une de vos lignes comporte moins de trois éléments séparés par un point-virgule. Même si vous déclarez des Values tant que tableau Ssortingng de trois éléments, affecter la variable au résultat de la fonction Ssortingng.Split() rend ceci inutile: votre tableau aura la longueur du tableau retourné. Si c’est moins, votre code va définitivement échouer.

Si ce n’est pas censé se produire, je vous suggère de faire une assertion dans votre code pour vous aider à déboguer:

 // ... Values = line1.Split(';'); // the following will make the debugger stop execution if line.Length is smaller than 3 Debug.Assert(line1.Length >= 3); // ... 

En remarque, je devrais mentionner qu’un lot INSERT serait beaucoup plus efficace. De plus, votre façon de déclarer et de réaffecter la variable cmd n’est pas tout à fait correcte. Et enfin, vous devez appeler Ssortingng.Replace sur vos valeurs pour vous assurer que les apostrophes sont doublées. Sinon, votre code sera ouvert aux attaques par injection SQL.

Quelques détails sur le comportement de votre code au moment de l’exécution:

 // This line declares a variable named Values and sets its value to // a new array of ssortingngs. However, this new array is never used // because the loop overwrites Values with a new array before doing // anything else with it. ssortingng[] Values = new ssortingng[3]; foreach (ssortingng line1 in lines) { Values = line1.Split(';'); // At this point in the code, whatever was previously stored in Values has been // tossed on the garbage heap, and Values now contains a brand new array containing // the results of splitting line1 on semicolons. // That means that it is no longer safe to assume how many elements the Values array has. // For example, if line1 is blank (which often happens at the end of a text file), then // Values will be an empty array, and trying to get anything out of it will throw an // exception ssortingng query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')"; cmd = new SqlCommand(query,con); cmd.ExecuteNonQuery(); } 

Semblable à la façon dont les valeurs continuent à être écrasées, SqlCommand créé en dehors de la boucle ne sera jamais utilisé. Il est prudent de placer ces deux déclarations dans la boucle. Le code suivant fait cela, et ajoute également une vérification d’erreur pour s’assurer qu’un nombre utilisable de valeurs a été extrait de la ligne. Il ignorera simplement les lignes qui ne sont pas assez longues – si cela ne vous convient pas, vous devrez peut-être créer votre propre code de traitement des erreurs plus complexe.

 foreach(ssortingng line in lines) { ssortingng[] values = line.split[';']; if(values.Length >= 3) { ssortingng query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')"; using (SqlCommand command = new SqlCommand(query, con)) { cmd.ExecuteNonQuery(); } } } 

Pour finir, le code ci-dessus pourrait être vulnérable aux pirates si vous l’utilisiez dans une application Web. Pensez à la commande qui pourrait être envoyée au serveur si vous traitez un fichier qui ressemble à ceci:

 1;2;3 4;5;6 7;8;9') DROP TABLE demooo SELECT DATALENGTH('1 

Une option plus sûre consiste à utiliser des requêtes paramétrées, ce qui vous aidera à vous protéger contre ce type d’attaque. Pour ce faire, ils séparent la commande de ses arguments, ce qui vous évite de transmettre des valeurs pour des arguments qui ressemblent à du code SQL. Voici un exemple de configuration de cette façon:

 ssortingng query = "INSERT INTO demooo VALUES (@val1, @val2, @val3); using (var command = new SqlCommand(query, con)) { command.Parameters.AddWithValue("@val1", Values[0]); command.Parameters.AddWithValue("@val2", Values[1]); command.Parameters.AddWithValue("@val3", Values[2]); command.ExecuteNonQuery(); } 

Essaye ça.

 ssortingng path = ssortingng.Concat(Server.MapPath("~/TempFiles/"), Fileupload1.FileName); ssortingng text = System.IO.File.ReadAllText(path); ssortingng[] lines = text.Split(' '); con.Open(); ssortingng[] Values; foreach (ssortingng line1 in lines) { Values = line1.Split(';'); if (Values.Length >= 3) { ssortingng query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')"; } else { //Some error occured } using (var cmd = new SqlCommand(query,con)) { cmd.ExecuteNonQuery(); } }