成员表达式不能转换为空的从十进制到对象 [英] Member Expression cannot convert to object from nullable decimal

查看:155
本文介绍了成员表达式不能转换为空的从十进制到对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个MVC项目,想通过Html.TextboxFor方法的属性的名称。这是我的视图模型

I am working on an MVC project and would like to pass the Html.TextboxFor method the name of a property. This is my viewmodel

public class RuleViewModel<T> where T : class, IValidatableObject
{
    private T _rule;
    public T RuleModel
    {
        get
        {
            return _rule
                ?? (_rule = Activator.CreateInstance<T>());
        }
    }

    public RuleMetadata Metadata { get; set; }

    public Expression<Func<RuleViewModel<T>, Object>> GetParameterByName(PropertyInfo pi)
    {
        var fieldName = Expression.Parameter(typeof(RuleViewModel<T>), "x");
        var fieldExpression = Expression.PropertyOrField(Expression.Property(fieldName, "RuleModel"), pi.Name);
        var exp = Expression.Lambda<Func<RuleViewModel<T>, Object>>(fieldExpression, fieldName);
        return exp;
    }

}



然后在视图我这样做

Then in the view I do this

  @foreach (var prop in Model.RuleModel.GetType().GetProperties())
    {
        var result = Model.Metadata.Columns.SingleOrDefault(m => m.ColumnName == prop.Name);
        if (result != null)
        {
            <td>
                @Html.TextBoxFor(Model.GetParameterByName(prop))
            </td>
        }
    }



现在的问题是,当属性的类型为十进制?,我得到一个不能转换为空的小数对象错误。我环顾四周,发现可以使用Expression.Convert来解决这个问题,但是当我这样做,我的观点得到一个错误

The problem is that when the property is of type decimal?, I get a cannot convert nullable decimal to object error. I looked around and found that you can use Expression.Convert to fix this but when I do that I get an error on the view

模板只能用于字段访问使用,属性访问,一维数组的索引,或单参数自定义索引表达式。

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

任何帮助,将不胜感激。这是我的工作,没有这一块是一潭死水概念项目的证明。

Any help would be appreciated. This is a proof of concept project that I'm working on and without this piece it is dead in the water.

推荐答案

的问题是,你不能只使用对象 TProperty 打电话时 TextBoxFor<的TModel, TProperty>()。该公司预计形式的lambda表达式 Func键<的TModel,TProperty> 和C#的变化规则是这样的: Func键<的TModel,小数? > 不是分配与 Func键LT兼容&;的TModel,对象> 。你也不能简单地用转换(),因为MVC内部不会接受一个lambda,其主体是转换表达式

The problem is that you can't just use object as TProperty when calling TextBoxFor<TModel, TProperty>(). It expects a lambda expression of the form Func<TModel, TProperty>, and the variance rules of C# are such that a Func<TModel, decimal?> is not assignment compatible with Func<TModel, object>. You also can't simply use Convert(), because the MVC internals won't accept a lambda whose body is a Convert expression.

在<什么EM> 的可以做的是使用动态绑定来调用 TextBoxFor<的TModel,TProperty>() 正确类型的参数:

What you can do is use dynamic binding to invoke TextBoxFor<TModel, TProperty>() with the correct type arguments:

public Expression GetParameterByName(PropertyInfo pi)
{
    var fieldName = Expression.Parameter(typeof(RuleViewModel<T>), "x");
    var fieldExpression = Expression.PropertyOrField(
        Expression.Property(fieldName, "RuleModel"),
        pi.Name);
    var exp = Expression.Lambda(
        typeof(Func<,>).MakeGenericType(typeof(RuleViewModel<T>), fieldExpression.Type),
        fieldExpression,
        fieldName);
    return exp;
}

// ...

@InputExtensions.TextBoxFor(Html, (dynamic)Model.GetParameterByName(prop))

这篇关于成员表达式不能转换为空的从十进制到对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆