我已经实现了一个MVC扩展来格式化我的应用程序中的数字。它基于找到的代码here。如下
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);
}
当我使用以下Razor语法行调用它时
@Html.DecimalBoxFor(model => Model.PointAttributes[i].Data.Y,"0.000", new { @class = "span1 number" })
我得到一个例外,因为我的扩展名中的变量'name'是一个空字符串。我已经尝试将var name行更改为this但它只给了我'Y'的属性名,而不是我需要将模型绑定回MVC的完整'Model.PointAttributes [i] .Data.Y'。 / p>
var name = ((expression.Body is MemberExpression ?((MemberExpression)expression.Body).Member : ((MemberExpression)((UnaryExpression)expression.Body).Operand).Member)).Name;
答案 0 :(得分:8)
尝试使用此功能:
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);
}
答案 1 :(得分:6)
这是一种已知的行为。我已经想出了编写我自己的ExpressionHelper
版本来处理这个特定情况。现在你有两个选择:
使用NuGet包:
Install-Package Mariuzzo.Web.Mvc.Extras
或者只需抓住the source code of the aforementioned ExpressionHelper并将其粘贴到您的项目中。
答案 2 :(得分:1)
这里有一个&#39;混合&#39;一:)
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);
}
这个更紧凑,可能是更好的解决方案:
答案 3 :(得分:0)
如果你可以在不使用可空类型的情况下离开它似乎工作(即删除?后双,或在我的情况下十进制)。所以
Expression<Func<TModel, double?>>
成为
Expression<Func<TModel, double>>.
如果你使用可空类型单步执行它,你会看到表达式中有一个convert()函数,它似乎是'问题'。我肯定和我一样,你会对如何使这个函数适用于可空类型感兴趣。
答案 4 :(得分:0)