2009-07-13 12 views
24

Sto utilizzando VSTS 2008 + C# + .Net 2.0. Quando si esegue la seguente dichiarazione, c'è FormatException generata dall'istruzione String.Format, qualsiasi idea che cosa è sbagliato?String.Format eccezione quando la stringa di formato contiene "{"

Qui è dove ottenere il template.html che sto usando. Voglio formattare questa parte m = {0} in 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?u4myvhbmmzg

EDIT 1:

Ecco il contenuto della mia 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> 

grazie a avdance, George

+1

Come sospetto, ci sono parentesi graffe negli stili e nel javascript. Non funzionerà a meno che tu non li sfugga, come string.Format trova un {e panico quando non riesce a trovare un intero e un}. –

+2

btw; non stai attualmente prendendo il risultato di string.Format (le stringhe .NET sono immutabili, quindi string.Format restituisce una ** nuova ** stringa, non aggiorna la stringa di input) –

+0

(risposto al commento) –

risposta

48

A occhio e croce, l'html contiene javascript o un'altra fonte di reggiseno ces ({ e }) che avrebbero tutti bisogno del raddoppio (a {{ e }}) per essere utilizzabili con string.Format. Mi aspetto che un token diverso (più ovvio) possa essere in ordine, ad esempio %%FILENAME%%. Quindi utilizzare regex o string.Replace.

Se si dispone di un singolo tag, string.Replace va bene; se hai un sacco, ci sono trucchi con regex e MatchEvaluator che potrebbero essere utili - like so ma con un modello di regex diverso.


Aggiornamento dopo l'esempio html aggiunto: utilizzerei sicuramente un diverso token; al livello più elementare:

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

e

template = template.Replace("%%FILENAME%%", "video.wmv"); 
+2

I secondo questo controllo per altre parentesi graffe. –

+0

Cool, Marc, mi piace la tua soluzione intelligente. – George2

+0

Marc, potresti spiegare cosa intendi "avrebbe bisogno di raddoppiare (a {{e}}) per essere utilizzabile con string.Format", sono confuso cosa significa aver bisogno di raddoppiare per essere utilizzabile con string.Format. – George2

1

Wat sono il contenuto della variabile 'template'?

Difficile dire cosa c'è di sbagliato nel codice, ma presumibilmente, la variabile del modello non contiene una stringa che come segnaposto. (come "questa è una stringa {0}").

Penso che dovresti fare uso degli strumenti forniti dal tuo IDE: eseguire il debug del codice, utilizzare gli orologi per ispezionare il contenuto della variabile del modello.

+0

Ho ha postato il mio template.html nel mio post originale nella sezione EDIT 1, qualsiasi idea che cosa è sbagliato? – George2

0

Cosa c'è nel file di modello?

se ci sono parentesi graffe che non sono del formato {int} o ci sono più di quanti sono gli argomenti per l'istruzione di formato, genererà un'eccezione.

Qual è il messaggio nell'eccezione?

È il tuo Css che lo sta facendo. Come somoene altro ha menzionato è necessario doa Regex sostituire o un gruppo di String.Replace comandi in un segno di fila ti variabili con %% %% VARIABLE_NAME e la sostituzione dell'uso stringa di sostituirli

+0

Ho pubblicato il mio template.html nel mio post originale nella sezione EDIT 1, qualsiasi idea cosa è sbagliato? – George2

+1

Il mancato {0} non causa un'eccezione. I parametri saranno semplicemente ignorati. –

+0

rimosso quella clausola. –

12

Il modello contiene { e } caratteri che devono essere sfuggiti, altrimenti confondono String.Format. Fuggirli usando {{ e }}.In alternativa, utilizzare un meccanismo diverso come String.Replace.

+0

Ho pubblicato il mio template.html nel mio post originale nella sezione EDIT 1, qualsiasi idea cosa è sbagliato? – George2

+1

le parentesi graffe. –

+0

Frederik, la soluzione è? – George2

6

string.Format() non gestisce { e } nella stringa di formato. Devi sostituire { con {{ e } con }} ovunque nel tuo file template.html. Tranne per il posto unico in cui si utilizza il segnaposto {0}.

Non molto elegante.

Invece, considerare l'utilizzo di un motore di template. Vedi http://csharp-source.net/open-source/template-engines per alcuni suggerimenti.

La soluzione migliore è utilizzare espressioni regolari (con MatchEvaluator) o string.Replace(), come suggerito da altre risposte.

Edit:

Ecco un esempio utilizzando il motore di template StringTemplate:

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

Cambiare una sola riga nel file template.html:

da:

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

a:

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

Quando il motore di template incontra $content$ nel modello, lo sostituisce con il valore del 'contenuto' attributo che si imposta utilizzando il codice.

Utilizzando StringTemplate, è possibile eseguire semplici cicli e condizionali all'interno del modello. Vedi the documentation.

+1

concordato. string.Format è un motore di template scadente per il modo in cui gestisce le parentesi graffe ({e}). –

+0

Ciao codeape, ho studiato il motore di template, ma ho confuso perché e come il motore di template si riferisce alla mia domanda? – George2

+0

Ciao Joe, in che modo il motore di template si riferisce alla mia domanda? Sono confuso, qualche commento? – George2

Problemi correlati