2009-07-13 4 views
24

Я использую VSTS 2008 + C# + .Net 2.0. При выполнении следующей инструкции существует исключение FormatException из инструкции String.Format, любые идеи, что не так?Исключение String.Format, когда строка формата содержит «{»

Здесь я могу найти шаблон.html. Я хочу отформатировать эту часть m = {0} в 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:

Вот содержание моего 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, Джордж

+1

Как и следовало ожидать, в обоих стилях и в javascript есть фигурные скобки. Это не сработает, если вы не избежите их, как string.Format находит {и панику, когда не может найти целое число и a}. –

+2

btw; вы не в настоящее время ловите результат string.Format (строки .NET неизменяемы, поэтому string.Format возвращает ** новую строку **, не обновляет строку ввода) –

+0

(ответил на комментарий) –

ответ

48

В догадке, html содержит javascript или другой источник brac ({ и }), которые должны были бы удвоиться (до {{ и }}) для использования с 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"); 
+2

I второй эта проверка для других фигурных скобок. –

+0

Прохладный, Марк, мне нравится ваше умное решение. – George2

+0

Марк, не могли бы вы объяснить, что вы имеете в виду: «все будут нуждаться в удвоении (чтобы {{и}}) для использования с string.Format», я смущен, что означает, что нужно удвоить, чтобы его можно было использовать с string.Format. – George2

1

Wat являются содержимое переменной 'шаблон'?

Сложно сказать, что не так с вашим кодом, но, предположительно, переменная шаблона не содержит строку, которая как владелец места. (Как «это некоторая строка {0}»).

Я думаю, что вы должны использовать инструменты, которые предоставляет ваша IDE: отлаживать код, использовать часы для проверки содержимого переменной шаблона.

+0

У меня есть отправил мой template.html в мой оригинальный пост в разделе EDIT 1, какие-то идеи, что не так? – George2

0

Что находится в файле шаблона?

Если есть фигурные скобки, которые не имеют формат {int}, или есть больше аргументов для оператора формата, это вызовет исключение.

Что такое сообщение в исключении?

Это ваш Css, который это делает. Как somoene еще упоминалось вам нужно DOA Regex заменить, или связка string.replace команды в знак строки вы переменные с %% %% VARIABLE_NAME и замена использование строки заменить их

+0

Я разместил свой template.html в своем оригинальном посте в разделе EDIT 1, какие-то идеи, что не так? – George2

+1

Отсутствие {0} не вызывает исключения. Параметры просто будут проигнорированы. –

+0

снял эту статью. –

12

Ваш шаблон содержит { и } символов, которые должны быть экранированы, в противном случае они путают String.Format. Побег их с помощью {{ и }}.Альтернативно, используйте другой механизм, такой как String.Replace.

+0

Я разместил свой template.html в своем оригинальном посте в разделе EDIT 1, какие-то идеи, что не так? – George2

+1

фигурные скобки. –

+0

Frederik, решение есть? – George2

6

string.Format() не обрабатывает { и } в строке формата. Вам необходимо заменить { на {{ и } с }} всюду в вашем файле template.html. За исключением одного места, где вы используете заполнитель {0}.

Не очень элегантный.

Вместо этого рассмотрите возможность использования механизма шаблонов. См. http://csharp-source.net/open-source/template-engines для некоторых предложений.

Следующее лучшее решение - использовать регулярные выражения (с MatchEvaluator) или string.Replace(), как предложено другими ответами.

Edit:

Вот пример использования шаблона двигателя 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$ в шаблоне, он заменяет его значением «содержания» атрибут, который вы задали при помощи кода.

Используя StringTemplate, вы можете создавать простые петли и условные обозначения в шаблоне. См. the documentation.

+1

Согласовано. string.Format - это паршивый механизм шаблонов из-за того, как он обрабатывает фигурные скобки ({и}). –

+0

Привет, код, я изучил механизм шаблонов, но смутил почему и как механизм шаблона относится к моему вопросу? – George2

+0

Привет, Джо, как механизм шаблонов относится к моему вопросу? Я смущен, любые комментарии? – George2