web-dev-qa-db-ja.com

フォーマット文字列に「{」が含まれている場合のString.Format例外

VSTS 2008 + C#+ .Net 2.0を使用しています。次のステートメントを実行すると、String.FormatステートメントからFormatExceptionがスローされます。

ここに私が使用している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

編集1:

これが私の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>

ジョージ、ありがとう

34
George2

テンプレートには、エスケープする必要がある{および}文字が含まれています。そうしないと、String.Formatが混乱します。 {{および}}を使用してエスケープします。または、String.Replaceなどの別のメカニズムを使用します。

17
Matt Howells

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$を検出すると、コードを使用して設定した 'content'属性の値に置き換えます。

StringTemplateを使用すると、テンプレート内で単純なループと条件を実行できます。 ドキュメント を参照してください。

7
codeape

「テンプレート」変数の内容は何ですか?

コードの何が悪いのかを言うのは難しいですが、おそらくテンプレート変数にはプレースホルダーとしての文字列が含まれていません。 (「これはいくつかの文字列{0}」のようです)。

IDEが提供するツールを使用する必要があります:コードをデバッグし、監視を使用してテンプレート変数の内容を検査します。

1

テンプレートファイルの内容

{int}形式ではない中括弧がある場合、またはformatステートメントの引数が複数ある場合は、例外がスローされます。

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

それをしているのはあなたのCssです。 somoeneが他に言及したように、正規表現置換または一連のString.Replaceコマンドを実行して、変数を%% VARIABLE_NAME %%でマークし、文字列置換を使用してそれらを置き換える必要があります

0
Omar Kooheji