格式字符串包含“{”时的String.Format异常

时间:2009-07-13 09:45:47

标签: c# .net 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>
感谢avdance, 乔治

5 个答案:

答案 0 :(得分:57)

猜测一下,html包含javascript或其他大括号({}),它们都需要加倍(到{{}})才能可与string.Format一起使用。我期望可能有一个不同的(更明显的)令牌,即%%FILENAME%%。然后使用正则表达式或string.Replace

如果你有一个标签,string.Replace就可以了;如果你有很多,有正则表达式和MatchEvaluator的技巧可能会有所帮助 - like so但有不同的正则表达式模式。


添加示例html后更新:我肯定会使用不同的令牌;在最基本的层面:

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

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

答案 1 :(得分:14)

您的模板包含需要转义的{}个字符,否则会混淆String.Format。使用{{}}来逃避它们。或者,使用其他机制,例如String.Replace

答案 2 :(得分: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文件中的一行:

从:

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

为:

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

当模板引擎在模板中遇到$content$时,它会将其替换为您使用代码设置的“content”属性的值。

使用StringTemplate,您可以在模板中进行简单的循环和条件化。请参阅the documentation

答案 3 :(得分:1)

Wat是'template'变量的内容吗?

很难说你的代码出了什么问题,但大概是模板变量不包含作为占位符的字符串。 (比如“这是一些字符串{0}”)。

我认为您应该使用IDE提供的工具:调试代码,使用watch来检查模板变量的内容。

答案 4 :(得分:0)

模板文件中有什么?

如果有大括号{int}的大括号,或者格式语句的参数不止,则会抛出异常。

例外中的消息是什么?

这是你的Css。正如其他人提到的那样,你需要做一个正则表达式替换,或者连续一堆String.Replace命令用%% VARIABLE_NAME %%标记变量并使用字符串替换来替换它们