-
-
Save dotnetchris/2170953 to your computer and use it in GitHub Desktop.
Updated HenriFormatter from Named Formats Redux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://haacked.com/archive/2009/01/14/named-formats-redux.aspx#70485 | |
using System; | |
using System.Text; | |
using System.Web; | |
using System.Web.UI; | |
namespace StringLib | |
{ | |
public static class HenriFormatter | |
{ | |
public static string HenriFormat(this string format, object source) | |
{ | |
if (format == null) | |
throw new ArgumentNullException("format"); | |
var result = new StringBuilder(format.Length * 2); | |
var expression = new StringBuilder(); | |
var e = format.GetEnumerator(); | |
while (e.MoveNext()) | |
{ | |
var ch = e.Current; | |
if (ch == '{') | |
{ | |
while (true) | |
{ | |
if (!e.MoveNext()) | |
throw new FormatException(); | |
ch = e.Current; | |
if (ch == '}') | |
{ | |
result.Append(OutExpression(source, expression.ToString())); | |
expression.Length = 0; | |
break; | |
} | |
if (ch == '{') | |
{ | |
result.Append(ch); | |
break; | |
} | |
expression.Append(ch); | |
} | |
} | |
else if (ch == '}') | |
{ | |
if (!e.MoveNext() || e.Current != '}') | |
throw new FormatException(); | |
result.Append('}'); | |
} | |
else | |
{ | |
result.Append(ch); | |
} | |
} | |
return result.ToString(); | |
} | |
private static string OutExpression(object source, string expression) | |
{ | |
string format = "{0}"; | |
int colonIndex = expression.IndexOf(':'); | |
if (colonIndex > 0) | |
{ | |
format = "{0:" + expression.Substring(colonIndex + 1) + "}"; | |
expression = expression.Substring(0, colonIndex); | |
} | |
try | |
{ | |
if (String.IsNullOrEmpty(format)) | |
{ | |
if (source is RouteData) | |
source = ((RouteData) (source)).Values; | |
var dict = source as IDictionary<string, object>; | |
return dict != null ? dict[expression].ToString() : (DataBinder.Eval(source, expression) ?? "").ToString(); | |
} | |
return DataBinder.Eval(source, expression, "{0:" + format + "}") ?? ""; | |
} | |
catch (HttpException) | |
{ | |
throw new FormatException(); | |
} | |
} | |
} | |
} |
Strange, but I think too that line #82 should be return DataBinder.Eval(source, expression, format) ?? "";
. Simply running "Hi {name}!".HenriFormat(new { name = "Henri" })
throws a FormatException.
Debugging to line #82 the value of the "{0:" + format + "}"
expression becomes this: "{0:{0}}"
(on .net 4.5.2)
After the change both of these pass, so format parameters are respected:
"Hi {name}!".HenriFormat(new { name = "Henri" }).Should().Be("Hi Henri!");
"{data:yyyy.MM}".HenriFormat(new { data = new DateTime(2015, 2, 1) }).Should().Be("2015.02");
btw do you still use it after several years?
@AkosLukacs github notifications are pretty stupid and just flood noise instead of actual important ones. I was using this around the time you posted. I haven't used it this year as i've been doing very high performance webscale development, generally trying to avoid string manipulation entirely.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Mm, I wasn't precise, the file gets compiled. I just got format exception when I tried to run it across tests.
Please check - you set 'string format = "{0}"' at line 63 and then since it is never empty, the last parameter for DataBinder.Eval becomes {0:{0}} which is definitely not what we want it to be.