Asp.net mvc 3 GetExpressionText(表达式)不返回我的属性的名称

Asp.net mvc 3 GetExpressionText(表达式)不返回我的属性的名称,asp.net-mvc-3,lambda,Asp.net Mvc 3,Lambda,我已经实现了一个MVC扩展来格式化我的应用程序中的数字。它基于找到的代码。详情如下: public static MvcHtmlString DecimalBoxFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, double?>> expression, string format, object htmlAttributes = null) { var na

我已经实现了一个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);
}
我得到一个异常,因为扩展名中的变量“name”是空字符串。我已尝试将var name行更改为该行,但它只为我提供属性名“Y”,而不是完整的“Model.PointAttributes[I].Data.Y”,我需要将该模型绑定回MVC

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

如果不使用可为空的类型就可以避免,那么它似乎可以工作(例如,在double之后删除?或在我的示例中删除decimal)。所以

表达式
变成

Expression<Func<TModel, double>>.  
表达式。

如果您在使用nullable类型的情况下仔细检查它,您将看到表达式中有一个convert()函数,这似乎是“问题”。我相信和我一样,您也会对如何使此函数也适用于可空类型感兴趣

尝试使用此功能:

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

这是一种已知的行为。我已经想出了写我自己的版本来处理那个特定的案例。现在您有两个选择:

  • 使用NuGet软件包:

    Install-Package Mariuzzo.Web.Mvc.Extras
    
  • 或者干脆把它粘到你的项目里


  • 我知道它是关闭的,但为了记录在案

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

    这里有一个“混合型”的:)

    public static void AddModelError(此ModelStateDictionary状态、表达式、字符串消息)
    {
    LambdaExpression LambdaExpression=null;
    string fieldName=string.Empty;
    if(expression.Body.NodeType==ExpressionType.Convert | | expression.Body.NodeType==ExpressionType.ConvertChecked)
    {
    lambdaExpression=Expression.Lambda(((UnaryExpression)Expression.Body).操作数,Expression.Parameters);
    fieldName=ExpressionHelper.GetExpressionText(lambdaExpression);
    }否则{
    fieldName=ExpressionHelper.GetExpressionText(表达式);
    }
    state.AddModelError(字段名、消息);
    }
    
    这一个更紧凑,可能是更好的解决方案:


    不幸的是,它必须是可空类型。这个答案让我找到了解决方案,我创建/发布了感谢@AarolamaBluenk,我会考虑你的建议,并最终改进自己。再次感谢。我们遇到了这个,这对我们来说非常有效。非常感谢。
        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);
        }
    
    Install-Package Mariuzzo.Web.Mvc.Extras
    
        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);
        }