6

我已经实现了一个 MVC 扩展来格式化我的应用程序中的数字。它基于此处找到的代码。如下

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" })

我得到一个例外,因为我的扩展中的变量“名称”是一个空字符串。我尝试将 var name 行更改为此,但它只给了我“Y”的属性名称,而不是我需要将模型绑定回 MVC 的完整“Model.PointAttributes[i].Data.Y”。

var name = ((expression.Body is MemberExpression ?((MemberExpression)expression.Body).Member : ((MemberExpression)((UnaryExpression)expression.Body).Operand).Member)).Name;
4

5 回答 5

9

尝试使用此功能:

    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);
    }
于 2013-02-20T13:59:48.477 回答
7

这是一种已知行为。我已经想出编写自己的版本ExpressionHelper来处理该特定情况。现在你有两个选择:

  1. 使用 NuGet 包:

    Install-Package Mariuzzo.Web.Mvc.Extras
    
  2. 或者只是获取上述 ExpressionHelper 的源代码并将其粘贴到您的项目中。

于 2013-02-21T14:35:45.733 回答
3

这是一个“混合”的:)

    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);
    }

这个更紧凑,可能是更好的解决方案:

https://stackoverflow.com/a/12689563/951001

于 2014-05-06T09:34:23.313 回答
0

如果您可以在不使用可为空类型的情况下逃脱,它似乎可以工作(即删除 ? 在双精度后,或者在我的情况下为十进制)。所以

Expression<Func<TModel, double?>> 

变成

Expression<Func<TModel, double>>.  

如果您使用可空类型逐步完成它,您会看到表达式中有一个 convert() 函数,这似乎是“问题”。我相信您会像我一样对如何使此函数也适用于可空类型感兴趣。

于 2012-06-03T05:43:33.127 回答
0

我知道它已经关闭,但为了记录在案;

这最好由模板处理,因此您可以指定您在模型中使用的数据类型以及它在模板中的表示方式(单一责任)。此外,您不需要修改 MVC 框架。

MSDN UiHint 属性

于 2013-08-23T11:29:55.140 回答