将属性表达式传递给从对象中选择值的方法

本文关键字:选择 方法 对象 表达式 属性 | 更新日期: 2023-09-27 18:09:29

我要做的是创建一个html扩展方法,在mvc项目中构建一组单选按钮。我知道我可以写一个for循环,但这将是一个非常有用的方法,可以在其他项目中重用,所以我想弄清楚这一点。

我想要做的是能够传递单选按钮所用于的模型属性的表达式(因此我可以将单选按钮命名为相同的东西并选择所选选项),作为选项的对象集合,以及用作单选按钮值的选项对象的属性。

这是我到目前为止所做的,但它不起作用。(我得到错误"无法转换方法组'值'到非委托类型'字符串'。您是否打算调用该方法?").

public static HtmlString RadioOptionsFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> modelExpression, 
        IEnumerable<object> radioOptions,  
        Expression<Func<object, string>> valueExpression)
    {
        StringBuilder sb = new StringBuilder();
        var propertyName = ((MemberExpression)(modelExpression.Body)).Member.Name;
        radioOptions.Select(el => sb.Append(htmlHelper.RadioButton(propertyName, valueExpression.Compile()(el))));
        return new HtmlString(sb.ToString());
    }

@Html.RadioOptionsFor(x => x.Category, Model.CategoryOptions, e => e.Value)

更新:好了,StriplingWarrior帮我找到了一个可行的解决方案。问题是将第二个表达式函数的形参声明为对象。它应该是一个泛型类型,所以我只需要为此更改方法声明。我还添加了一个助手方法来构建带有包装标签元素的单选按钮。我还做了一些linq字符串构建这样我就不用在集合上循环两次了。最后,我添加了选择模型的当前值和删除单选按钮元素的重复id。这是最终的解决方案。

public static string RadioButtonWithLabel<TModel>(this HtmlHelper<TModel> htmlHelper, string name, string value, string selectedValue)
    {
        var sb = new StringBuilder();
        sb.Append("<label for='"").Append(name).AppendLine("'">")
            .AppendLine(htmlHelper.RadioButton(name, value, selectedValue.Equals(value), new { id = "" }).ToString())
            .Append(value).AppendLine("</label>");
        return sb.ToString();
    }
    public static HtmlString RadioOptionsFor<TModel, TProperty, TElement>(this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> modelExpression, 
        string selectedValue,
        IEnumerable<TElement> radioOptions,  
        Expression<Func<TElement, string>> valueExpression)
    {
        var propertyName = ((MemberExpression)(modelExpression.Body)).Member.Name;
        var result = radioOptions.Aggregate(new StringBuilder(), (sb, el) => sb.Append(htmlHelper.RadioButtonWithLabel(propertyName, valueExpression.Compile()(el), selectedValue)));
        return new HtmlString(result.ToString());
    }

像这样调用

@Html.RadioOptionsFor(x => x.Category, Model.Category, Model.CategoryOptions, e => e.Value)

将属性表达式传递给从对象中选择值的方法

Expression<Func<object, string>> valueExpression期望表达式产生一个字符串:e.Value的类型是什么?

似乎e.Value不应该存在,因为e是一个对象。这是一个扩展方法吗?如果是这样,您可能需要传递:

e => e.Value()

所以,破译你的错误信息:它不能转换"值"(这是一个方法或委托)到一个string的表达式所期望的:你打算调用该方法来产生一个字符串吗?