public
Last active — forked from atifaziz/HenriFormatter.cs

Updated HenriFormatter from Named Formats Redux

  • Download Gist
HenriFormatter.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
// 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();
}
}
}
}

Add support for anonymous object, RouteData, and RouteValueDictionary

You may consider changing the last parameter to 'Eval' from "{0:" + format + "}" to just 'format' at line 82. It doesn't compile the way it is

@isamochernov are you targeting the full .NET4 profile? This the exact file I'm using.

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.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.