web-dev-qa-db-fra.com

String.Format: la chaîne d'entrée n'était pas dans un format correct

Le code suivant me donne toujours une erreur en disant que la chaîne d'entrée n'était pas dans un format correct, mais je suis sûr qu'elle est correcte, n'est-ce pas?

int id = 112;

String[] newData = { "1", "2", "21", "reidb", "reidb", "reidb", "reidb", "aa", 
                      "Some description", "11", "2012-02-28", "2012-01-29", "true", "1", "1", 
                      "true", "note note note", "true", "1", "2011-12-03", "45"};

String data = "{ cmd: \"save magellan deal\", data: { id: {0} , AId: {1}, " +
            "CId: {2}, CCId:{3}, LA: \"{4}\", BA: \"{5}\" , " +
            "LSA: \"{6}\" , BSA: \"{7}\" , \"path: \"{8}\"," +
            "dscp: \"{9}\", SI: \"{10}\", CD: \"{11}\", " +
            "period: \"{12}\", IsStatic: {13}, LSD: {14}, LC: {15}, RB: {16},} " +
            "Notes: \"{17}\", IsEE: {18}, RBy: {19}, DPDD: \"{20}\", LId: {21} } }";


String cmd = String.Format(data, id.toString(), newData);

Quelqu'un a des idées?

=== EDIT ===

après avoir corrigé les accolades, une nouvelle erreur de "Index (basé sur zéro) doit être supérieure ou égale à zéro et inférieure à la taille de la liste d'arguments." est donnée. le newData a 21 et plus l'id.toString (), devrait être exact 22?

33
jamesdeath123

Échappez les "{", "}" (en les dupliquant) dans la chaîne de format:

"{{ cmd: \"save magellan deal\", data: {{ id: {0} , AId: {1}, " +
"CId: {2}, CCId:{3}, LA: \"{4}\", BA: \"{5}\" , " +
"LSA: \"{6}\" , BSA: \"{7}\" , \"path: \"{8}\"," +
"dscp: \"{9}\", SI: \"{10}\", CD: \"{11}\", " +
"period: \"{12}\", IsStatic: {13}, LSD: {14}, LC: {15}, RB: {16},}} " +
"Notes: \"{17}\", IsEE: {18}, RBy: {19}, DPDD: \"{20}\", LId: {21} }} }}"

Et vous avez 22 éléments dans la chaîne de format et 21 dans le tableau.

71
Cédric Bignon

Vous avez 21 éléments dans newData mais utilisez 22 espaces réservés (numérotés de 0 à 21).

De plus, vous devez échapper le littéral '{' dans vos données d'entrée

Les accolades d'ouverture et de fermeture sont interprétées comme le début et la fin d'un élément de format. Par conséquent, vous devez utiliser une séquence d'échappement pour afficher une accolade d'ouverture littérale ou une accolade de fermeture. Spécifiez deux accolades ouvrantes ("{{") dans le texte fixe pour afficher une accolade ouvrante ("{"), ou deux accolades fermantes ("}}") pour afficher une accolade fermante ("}"). Les accolades dans un élément de format sont interprétées séquentiellement dans l'ordre où elles sont rencontrées. L'interprétation des accolades imbriquées n'est pas prise en charge.

http://msdn.Microsoft.com/en-us/library/txafckwd.aspx

8
Eric J.

J'en ai dit autant dans les commentaires, mais je pense que cela mérite une réponse maintenant:

N'utilisez pas string.Format (dans ce cas). C'est plus lent et moins lisible. Utilisez simplement la concaténation de chaînes simples avec des noms de variables significatifs si vous avez besoin de concaténations complexes - celles-ci seront plus rapides et plus faciles à gérer. Plus rapide car pour un nombre fixe de segments, tout simplement + est l'option la plus rapide en raison des optimisations du compilateur, et plus maintenable car le lecteur peut voir le contexte dans la chaîne dans laquelle la variable est placée.

Comme l'a noté Hans Passant, il semble que vous créez un littéral javascript. Si c'est le cas, envisagez plutôt un sérialiseur Json comme Json.NET :

JsonConvert.SerializeObject(new {
    cmd = "save magellan deal",
    data = new {
        id = 12345, AId = 1, CId = 2, CCId = 21,
        LA = "reidb", BA = "reidb", LSA = "reidb", BSA = "reidb",
        path = "aa", dscp = "Some description", SI = 11,
        CD = "2012-02-28", period = "2012-01-29",
        IsStatic = true, LSD = 1, LC = 1, RB = true,
    },
    Notes = "note note note",
    IsEE = true, RBy = 1, DPDD = "2011-12-03", LId = 45
})

Tandis que Json.NET prend en charge DateTime la sérialisation, il n'y a pas de format standardisé pour les dates dans JS, donc celles-ci sont sérialisées sous forme de chaînes au format iso 8601. Ce n'est peut-être pas ce dont vous avez besoin, d'où les chaînes de date dans cet exemple - j'essaierais d'abord le format iso, car c'est la solution la plus simple.

3
Eamon Nerbonne

En plus d'échapper à vos accolades, essayez également de changer votre String[] définition à:

int id = 112;

String[] newData = {id.ToString(), "1", "2", "21", "reidb", "reidb", "reidb", "reidb", "aa", 
          "Some description", "11", "2012-02-28", "2012-01-29", "true", "1", "1", 
          "true", "note note note", "true", "1", "2011-12-03", "45"};

et changez votre String.Format à:

String cmd = String.Format(data,newData);
2
Mark Hall

Quoi

String cmd = String.Format(data, id.toString(), newData);  

fait est: essayer de formater les données String, en utilisant seulement 2 chaînes..pas 22 !!
Lesquels? ... 1) id.ToString () et 2) newData.ToString ()
C'est évidemment faux

Comment pouvez-vous voir que c'est le problème ...? Laissez juste {0} et {1} dans la chaîne de données et imprimez-le. Il se compile bien et voyez ce que vous obtenez.
Bien sûr, vous devez utiliser {{au lieu de {où vous voulez un littéral de chaîne

Solution entièrement fonctionnelle:

int id = 112;

String[] newData = { id.ToString(),"1", "2", "21", "reidb", "reidb", "reidb", "reidb", "aa", 
                  "Some description", "11", "2012-02-28", "2012-01-29", "true", "1", "1", 
                  "true", "note note note", "true", "1", "2011-12-03", "45"};

String data = "{{ cmd: \"save magellan deal\", data: {{ id: {0} , AId: {1}, " +
                    "CId: {2}, CCId:{3}, LA: \"{4}\", BA: \"{5}\" , " +
                    "LSA: \"{6}\" , BSA: \"{7}\" , \"path: \"{8}\"," +
                    "dscp: \"{9}\", SI: \"{10}\", CD: \"{11}\", " +
                    "period: \"{12}\", IsStatic: {13}, LSD: {14}, LC: {15}, RB: {16},}} " +
                    "Notes: \"{17}\", IsEE: {18}, RBy: {19}, DPDD: \"{20}\", LId: {21} }} }}";


String cmd = String.Format(data, newData);
1
George