-3

I have a string variable called reason for failure which contains user added text for instance the following:

({0}) on arm ({1}} (82) Kits

Now this variable is part of a method where I am using string.format. I need the string.format to not confuse with {0} {1} in the text of the above variable because I am getting the the exception, Input string was not in correct format

tam tam
  • 1,870
  • 2
  • 21
  • 46

3 Answers3

2

The reason you're getting the exception, The input string is not in the correct format is due to the way you're constructing the string. In your variable you have two closing braces where string.Format expects only one: on arm ({1}}. If you add this variable as a parameter to String.Format as shown in the first example below, it should resolve this issue.

Otherwise, if you are saying that the variable serviceEntry.ReasonForFailure contains the characters {0} and {1}, and that when you place this variable inside a String.Format, those characters are being replaced by the String.Format arguments, then this is by design, at least the way you're constructing your string.

Instead of inserting your variable in the string using the + operator, include it as another parameter to the String.Format call. This way, the {0} in your variable will be preserved.

message.Body = string.Format(
    "<html><body>Request is complete<br/>" + 
    "Service Request initiated by you is Complete<br/>" +
    "Please use the following link to access " +
    "<a href=\"{0}{1}\">{0}{1}</a><br/>" +
    "Reason For Failure: {2}<br/></body></html>",
    RunLogURL, runLogID, serviceEntry.ReasonForFailure);

Now, if you want to replace the {0} and {1} in serviceEntry.ReasonForFailure with some other values, you can nest a String.Format inside another:

serviceEntry.ReasonForFailure = "10003 Insufficient Liquid Level detected at " +
    "pipettor channel ({0}) on arm ({1}) (82)";
var channelId = 87;
var armId = 42;

message.Body = string.Format(
    "<html><body>Request is complete<br/>" +
    "Service Request initiated by you is Complete<br/>" +
    "Please use the following link to access " +
    "<a href=\"{0}{1}\">{0}{1}</a><br/>" +
    "Reason For Failure: {2}<br/></body></html>",
    RunLogURL, runLogID, 
    String.Format(serviceEntry.ReasonForFailure, channelId, armId));

Or you can do it in two operations:

serviceEntry.ReasonForFailure = "10003 Insufficient Liquid Level detected at " +
    "pipettor channel ({0}) on arm ({1}) (82)";

var channelId = 87;
var armId = 42;

var reasonForFailure = String.Format(serviceEntry.ReasonForFailure, channelId, armId);

message.Body = string.Format(
    "<html><body>Request is complete<br/>" +
    "Service Request initiated by you is Complete<br/>" +
    "Please use the following link to access " +
    "<a href=\"{0}{1}\">{0}{1}</a><br/>" +
    "Reason For Failure: {2}<br/></body></html>",
    RunLogURL, runLogID, reasonForFailure);
Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • No the characters are not being replaced in this string. My intent is to leave the value of this variable as is and not replace with anything. I am getting the exception, Input string was not in correct format – tam tam Sep 24 '14 at 21:46
  • Ahh, I see. I think the first example above will solve that issue for you, then. Your variable has two closing braces where `String.Format` expects only one. – Rufus L Sep 24 '14 at 21:50
  • Notice I had to 'fix' your input string in my second and third examples (where I did a string.format on the variable value). – Rufus L Sep 24 '14 at 21:53
1

The problem is that your variable serviceEntry.ReasonForFailure contains a format item. If don't want them to be treated as format items you'll have to escape them with an extra set of braces. For instance: {0} becomes {{0}} as explained here.

The quick and dirty solution to your problem would be to replace all opening and closing braces by a double brace:

"Reason For Failure:"  + serviceEntry.ReasonForFailure.Replace("{","{{").Replace("}","}}") + "<br/>"

A better solution would be to do the replacement using a regular expression:

public string EscapeCurlyBraces(string value)
{
    string strRegex = @"(\{\d+\})";
    Regex myRegex = new Regex(strRegex, RegexOptions.None);
    string strReplace = @"{$1}";

    return myRegex.Replace(value, strReplace);
}

And then use it like this:

"Reason For Failure:"  + EscapeCurlyBraces(serviceEntry.ReasonForFailure) + "<br/>"

Update I suggest you ditch the current solution and rewrite it using a StringBuilder:

var emailBody = new StringBuilder();
emailBody.Append("<html><body>RSLMS - Service Request is complete<br/>");
emailBody.Append("Service Request initiated by you is Complete <br/>");
emailBody.AppendFormat("Please use the following link to access Run Log Entry <a href=\"{0}{1}\">{0}{1}</a><br/>", RunLogURL, runLogID);
// ommited some lines
emailBody.AppendFormat("Service ID: {0}<br/><br/>", serviceEntry.ID.ToString());
// ommited some lines
emailBody.AppendFormat("Reason For Failure: {0}<br/><br/>", serviceEntry.ReasonForFailure);
emailBody.Append("Thank you <br/> RSLMS Administrator <br/></body></html>");           

message.Body = emailBody.ToString();
Community
  • 1
  • 1
venerik
  • 5,766
  • 2
  • 33
  • 43
  • Well its a user added text so I am not certain it would always have those characters or what other new characters they would add :). I could enforce some javascript in the text box which would stop them to add those variables but I have no issues saving this value to the database column. The problem only happens in the method where I am composing an email. I am trying out your resolution, seems helpful – tam tam Sep 24 '14 at 21:58
  • Giving this new information your solution is flawed IMHO. If you want to insert user generated text in an HTML mail you certainly need to HTML encode that string. And I hope you're preventing your database from SQL injection too... – venerik Sep 24 '14 at 22:06
  • Should I just encode the string before I format the body of the message. I tried that and still the same error] – tam tam Sep 24 '14 at 22:49
0

Since you have two String.Format, you didnt provide parameter for the external , lets say you have x and y for the external Format, this is what you need to do. You need to do double curly braces for those you want to escape from the inner format as in :

 var reasonForFailure = "({{0}}) on arm ({{1}}) (82) Kits should still have 50 tests left after run, but it seems like the instrument is not able to pipette anymore from the kits.";
            var message = string.Format(string.Format(
                                    "<html><body>Request is complete<br/>" +
                                    "Service Request initiated by you is Complete" + " <br/> " +
                                    "Please use the following link to access <a href=\"{0}{1}\">{0}{1}</a> <br/>" +
                                    "Reason For Failure:  " + reasonForFailure+"<br/>" +
                                    "</body></html>", RunLogURL, runLogID),x,y);
Dan Hunex
  • 5,172
  • 2
  • 27
  • 38