2009-07-13 18 views
24

VSTS 2008 + C#+ .Net 2.0を使用しています。次の文を実行すると、String.Format文からFormatExceptionがスローされます。何が間違っていますか?フォーマット文字列に "{"が含まれている場合のString.Format例外

ここで私が使用しているtemplate.htmlを入手できます。私はtemplate.htmlのこの部分をm = {0}にフォーマットしたいと思います。

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:ここでは

は私template.htmlのコンテンツである、avdanceで

<!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> 

おかげで、 ジョージ

+1

疑わしいように、スタイルとJavaScriptの両方に中カッコがあります。 string.Formatは、整数とaを見つけることができないときに{とパニックを検出するので、あなたがそれらをエスケープしない限り動作しません。 –

+2

btw;あなたは現在string.Formatの結果をキャッチしていません(.NETの文字列は不変なので、string.Formatは**新しい**文字列を返します;入力文字列を更新しません) –

+0

(コメントに返信) –

答えて

48

の推測では、 htmlにはjavascriptやブラジャーの別のソースが含まれています({{および}}へ)をstring.Formatと一緒に使用できるようにする必要があります。私は別の(もっと明白な)トークンが順番に並ぶことを期待しています。つまり、%%FILENAME%%です。次に、正規表現またはstring.Replaceのいずれかを使用します。

タグが1つの場合、string.Replaceは問題ありません。もしあなたがたくさんあるなら、正規表現とMatchEvaluatorの助けを得ているかもしれない - like soのトリックがありますが、正規表現のパターンは異なります。


例htmlを追加した後の更新:私は間違いなく別のトークンを使用します。最も基本的なレベルで:

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

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

I secondこの中かっこのチェック。 –

+0

クール、マーク、私はあなたのスマートなソリューションが好きです。 – George2

+0

Marc、string.Formatで使えるようにするために、倍増する必要があることを混乱させています。 – George2

1

ワットは、 'テンプレート' 変数の内容は?

あなたのコードに間違いがあるとは言い難いですが、テンプレート変数にはプレースホルダとしての文字列が含まれていない可能性があります。 (「これは一部の文字列{0}」と似ています)。

私はあなたのIDEが提供するツールを利用するべきだと思います。コードをデバッグし、時計を使ってテンプレート変数の内容を調べます。

+0

私は持っています私のtemplate.htmlをEDIT 1のセクションのオリジナルの投稿に投稿しました。何が間違っていますか? – George2

0

テンプレートファイルは何ですか?

{int}の形式でない中かっこがあるか、またはformat文の引数が複数ある場合、例外がスローされます。

例外のメッセージは何ですか?

これはあなたのCss thatsです。文字列の置換は、%% VARIABLE_NAME %%で変数をマークし、置換文字列を使用して置き換えます。

+0

EDIT 1のセクションのオリジナルの投稿にtemplate.htmlを投稿しました。何が間違っていますか? – George2

+1

{0}を持たないため例外が発生しません。パラメータは無視されます。 –

+0

はその句を削除しました。 –

12

テンプレートには{}が含まれています文字をエスケープする必要があります。それ以外の場合は、String.Formatを混同します。 {{}}を使用してそれらをエスケープします。あるいは、String.Replaceのような別のメカニズムを使用してください。

+0

EDIT 1のセクションのオリジナルの投稿にtemplate.htmlを投稿しました。何が間違っていますか? – George2

+1

中括弧。 –

+0

フレデリック、解決策は? – George2

6

string.Format()は、書式文字列に{ととを処理しません。 {{{および}と置き換える必要があります。template.htmlファイルのどこでも}}と置き換えてください。 {0}プレースホルダを使用する単一の場所を除きます。

あまり優雅ではありません。

代わりに、テンプレートエンジンの使用を検討してください。いくつかの提案については、http://csharp-source.net/open-source/template-enginesを参照してください。

次善策は、他の回答で示唆されているように、正規表現(MatchEvaluator)またはstring.Replace()を使用することです。

編集:

ここStringTemplateテンプレートエンジンを使用した例です:

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

変更し、あなたのtemplate.htmlファイル内の1行:

から:

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

〜へ:

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

テンプレートエンジンは、テンプレートで$content$に遭遇すると、それはあなたがコードを使用して設定する「コンテンツ」属性の値に置き換えられます。

StringTemplateを使用すると、テンプレート内で簡単なループと条件文を実行できます。 the documentationを参照してください。

+1

合意。 string.Formatは、中カッコ({と})を処理する方法のおかげで、ひどいテンプレートエンジンです。 –

+0

こんにちは、私はテンプレートエンジンを勉強しましたが、なぜテンプレートエンジンが私の質問に関係するのか混乱しましたか? – George2

+0

こんにちはJoe、テンプレートエンジンが私の質問にどう関係していますか?私は混乱しています、どんなコメントですか? – George2

関連する問題