I have implemented a MVC Extension to format the numbers in my application. It is based off the code found here. And is as follows
public static MvcHtmlString DecimalBoxFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, double?>> expression, string format, object htmlAttributes = null)
{
var name = ExpressionHelper.GetExpressionText(expression);
double? dec = expression.Compile().Invoke(html.ViewData.Model);
var value = dec.HasValue ? (!string.IsNullOrEmpty(format) ? dec.Value.ToString(format) : dec.Value.ToString()): "";
return html.TextBox(name, value, htmlAttributes);
}
When I call it with the following line of Razor syntax
@Html.DecimalBoxFor(model => Model.PointAttributes[i].Data.Y,"0.000", new { @class = "span1 number" })
I get an exception because the variable 'name' in my extension is an empty string. I have tried changing the var name line to this but it only gives me the property name of 'Y' and not the full 'Model.PointAttributes[i].Data.Y' that I need to bind the model back for MVC.
var name = ((expression.Body is MemberExpression ?((MemberExpression)expression.Body).Member : ((MemberExpression)((UnaryExpression)expression.Body).Operand).Member)).Name;
Try using this function:
static public string GetExpressionText(LambdaExpression p)
{
if (p.Body.NodeType == ExpressionType.Convert || p.Body.NodeType == ExpressionType.ConvertChecked)
{
p = Expression.Lambda(((UnaryExpression)p.Body).Operand,
p.Parameters);
}
return ExpressionHelper.GetExpressionText(p);
}
This is a known behavior. I have figured out writing my own version of ExpressionHelper
that handle that specific case. Now you have two option:
Use the NuGet package:
Install-Package Mariuzzo.Web.Mvc.Extras
Or just grab the source code of the aforementioned ExpressionHelper and glue it into your project.
Here a 'hybrid' one :)
public static void AddModelError<TModel>(this ModelStateDictionary state, Expression<Func<TModel, object>> expression, string message)
{
LambdaExpression lambdaExpression = null;
string fieldName = string.Empty;
if (expression.Body.NodeType == ExpressionType.Convert || expression.Body.NodeType == ExpressionType.ConvertChecked)
{
lambdaExpression = Expression.Lambda(((UnaryExpression)expression.Body).Operand, expression.Parameters);
fieldName = ExpressionHelper.GetExpressionText(lambdaExpression);
} else {
fieldName = ExpressionHelper.GetExpressionText(expression);
}
state.AddModelError(fieldName, message);
}
This one is more compact and probably a better solution:
https://stackoverflow.com/a/12689563/951001
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With