web-dev-qa-db-fra.com

String.Format Exception lorsque le format String contient "{"

J'utilise VSTS 2008 + C # + .NET 2.0. Lors de l'exécution de la déclaration suivante, il existe une énoncée de formatException à partir de String.Format, des idées ce qui ne va pas?

Voici où obtenir le template.html j'utilise. Je veux formater cette partie m = {0} dans template.html.

    string template = String.Empty;
    using (StreamReader textFile = new StreamReader("template.html"))
    {
        template = textFile.ReadToEnd();
        String.Format(template, "video.wmv");
    }

http://www.mediafire.com/download.php?u4myvhbmmmzg

Éditer 1:

Voici le contenu de mon template.html,

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<!-- saved from url=(0014)about:internet -->
<head>
    <title>Silverlight Project Test Page </title>

    <style type="text/css">
    html, body {
        height: 100%;
        overflow: auto;
    }
    body {
        padding: 0;
        margin: 0;
    }
    #silverlightControlHost {
        height: 100%;
    }
    </style>

    <script type="text/javascript">
        function onSilverlightError(sender, args) {

            var appSource = "";
            if (sender != null && sender != 0) {
                appSource = sender.getHost().Source;
            } 
            var errorType = args.ErrorType;
            var iErrorCode = args.ErrorCode;

            var errMsg = "Unhandled Error in Silverlight 2 Application " +  appSource + "\n" ;

            errMsg += "Code: "+ iErrorCode + "    \n";
            errMsg += "Category: " + errorType + "       \n";
            errMsg += "Message: " + args.ErrorMessage + "     \n";

            if (errorType == "ParserError")
            {
                errMsg += "File: " + args.xamlFile + "     \n";
                errMsg += "Line: " + args.lineNumber + "     \n";
                errMsg += "Position: " + args.charPosition + "     \n";
            }
            else if (errorType == "RuntimeError")
            {           
                if (args.lineNumber != 0)
                {
                    errMsg += "Line: " + args.lineNumber + "     \n";
                    errMsg += "Position: " +  args.charPosition + "     \n";
                }
                errMsg += "MethodName: " + args.methodName + "     \n";
            }

            throw new Error(errMsg);
        }
    </script>
</head>

<body>
    <!-- Runtime errors from Silverlight will be displayed here.
    This will contain debugging information and should be removed or hidden when debugging is completed -->
    <div id='errorLocation' style="font-size: small;color: Gray;"></div>

    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight," type="application/x-silverlight-2" width="500" height="240">
            <param name="source" value="ClientBin/VideoPlayer.xap"/>
            <param name="onerror" value="onSilverlightError" />
            <param name="background" value="white" />
            <param name="initParams" value="cc=true,markers=true,m={0}" />
            <a href="http://go.Microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;">
                <img src="http://go.Microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
            </a>
        </object>
        <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
    </div>
</body>
</html>

merci à Avdance, George

34
George2

À une conjecture, le HTML contient JavaScript ou une autre source d'accolades ({ et }) qui aurait tous besoin de doubler (à {{ et }}) être utilisable avec string.Format. Je m'attends à ce qu'un jeton différent (plus évident) peut être en ordre, c'est-à-dire %%FILENAME%%. Ensuite, utilisez soit regex ou string.Replace.

Si vous avez une seule étiquette, string.Replace c'est bien; Si vous avez beaucoup, il y a des astuces avec regex et MatchEvaluator qui peut être utile - comme SO mais avec un modèle de regex différent.


Mise à jour après l'exemple HTML ajouté: J'utiliserais certainement un jeton différent; Au niveau le plus élémentaire:

<param name="initParams" value="cc=true,markers=true,m=%%FILENAME%%" />

et

template = template.Replace("%%FILENAME%%", "video.wmv");
63
Marc Gravell

Votre modèle contient { et } caractères qui doivent être échappés, sinon ils confondent String.Format. Échappez-leur en utilisant {{ et }}. Alternativement, utilisez un mécanisme différent tel que String.Replace.

17
Matt Howells

string.format () ne gère pas { et } dans la chaîne de format. Vous devez remplacer { avec {{ et } avec }} partout dans votre template.html déposer. Sauf pour le seul endroit où vous utilisez le {0} espace réservé.

Pas très élégant.

Au lieu de cela, envisagez d'utiliser un moteur de modèle. Voir http://cshaarp-source.net/open-source/template-engines Pour certaines suggestions.

La meilleure solution consiste à utiliser des regexes (avec matchevaluator) ou String.replace (), comme suggéré par d'autres réponses.

Edit:

Voici un exemple utilisant le moteur de modèle StringTemplate:

StringTemplate htmlpage = new StringTemplate(File.ReadAllText("template.html"));
htmlpage.SetAttribute("content", "video.wmv");
Console.WriteLine(htmlpage.ToString());

Changer une ligne unique dans votre template.html déposer:

de:

<param name="initParams" value="cc=true,markers=true,m={0}" />

à:

<param name="initParams" value="cc=true,markers=true,m=$content$" />

Lorsque le moteur de modèle rencontre $content$ Dans le modèle, il le remplace avec la valeur de l'attribut "contenu" que vous définissez à l'aide du code.

À l'aide de StringTemplate, vous pouvez faire une boucle simple et des conditionnels dans votre modèle. Voir la documentation .

7
codeape

Wat sont le contenu de la variable "modèle"?

Difficile de dire ce qui ne va pas avec votre code, mais probablement, la variable de modèle ne contient pas de chaîne qui en tant que porte-lieu. (Comme "ceci est une chaîne {0}").

Je pense que vous devez utiliser les outils de votre IDE Fournit: déboguer le code, utilisez des montres pour inspecter le contenu de la variable de modèle.

1
Frederik Gheysels

Quoi de dans le fichier de modèle?

s'il y a des supports bouclés qui ne sont pas du format {INT} ou il y a plus que des arguments pour l'instruction FORMAT, cela lancera une exception.

Quel est le message à l'exception?

C'est votre CSS qui le fait. Comme l'a mentionné le somoe d'autre que vous avez mentionné, vous devrez faire une doa Regex remplacer, ou une bouquet de commandes string.replace dans une marque de rangée Vous avez des variables avec %% variable_name %% et utilisez le remplacement de chaîne pour les remplacer.

0
Omar Kooheji