在MVC 3中使用LINQ表达式自定义html帮助器

时间:2012-08-23 12:47:29

标签: c# asp.net-mvc-3 html-helper

我正在使用表达式构建一个自定义HTML帮助器来绘制标签云,其中进入标签云的数据来自表达式。我会让代码在这里谈谈:

查看模型

public class ViewModel
{
    public IList<MyType> MyTypes { get; set; }
    public IList<MyOtherType> MyOtherTypes { get; set; }
}

查看

<div>
    @Html.TagCloudFor(m => m.MyTypes)
</div>

<div>
    @Html.TagCloudFor(m => m.MyOtherTypes)
</div>

辅助

public static MvcHtmlString TagCloudFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) where TProperty : IList<MyType> where TProperty : IList<MyOtherType>
{
    // So my actual question here is: how do I get my IList<TProperty> collection 
    // so I can iterate through and build my HTML control
}

我已快速浏览并完成了常规的Google搜索,但我似乎无法找到具体的答案。我认为它位于expression.Compile().Invoke()区域的某个地方,但我不确定要通过的正确参数是什么。

我还应该提到MyTypeMyOtherType具有类似Id的属性,但这里没有继承,它们是完全独立的对象,因此我限制了我的{{1} } TPropertyIList<MyType>。我在这里走错了道路,我感觉这样的事情应该是显而易见的,但我的大脑并没有在玩。

2 个答案:

答案 0 :(得分:9)

以下应该这样做:

public static MvcHtmlString TagCloudFor<TModel , TProperty>( this HtmlHelper<TModel> helper , Expression<Func<TModel , TProperty>> expression )
        where TProperty : IList<MyType>, IList<MyOtherType> {

        //grab model from view
        TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
        //invoke model property via expression
        TProperty collection = expression.Compile().Invoke(model);

        //iterate through collection after casting as IEnumerable to remove ambiguousity
        foreach( var item in (System.Collections.IEnumerable)collection ) {
            //do whatever you want
        }

    }

答案 1 :(得分:1)

怎么样......

public static MvcHtmlString TagCloudFor<TModel , TItemType>( this HtmlHelper<TModel> helper , Expression<Func<TModel , IEnumerable<TItemType>>> expression ) 
// optional --- Where TItemType : MyCommonInterface
 { 

        TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model; 
        //invoke model property via expression 
        IEnumerable<TItemType> collection = expression.Compile().Invoke(model); 

        foreach( var item in collection ) { 
            //do whatever you want 
        } 

    }