【问题标题】:Custom html helper with LINQ expression in MVC 3MVC 3 中带有 LINQ 表达式的自定义 html 助手
【发布时间】:2012-08-23 21:23:26
【问题描述】:

我正在构建一个带有表达式的自定义 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 的相似属性,但这里没有继承,它们是完全独立的对象,因此我将TProperty 限制为IList&lt;MyType&gt; 和@987654330 @。我是不是走错了路,我感觉这应该是显而易见的,但我的大脑没有在玩。

【问题讨论】:

  • 如果你必须约束,一个 TProperty: IList 和一个 TProperty: IList 和 MyType 和 MyOtherType 不兼容的地方,比它不起作用。两个约束都适用。
  • @Maarten:是的,我也这么认为,我现在已经删除了第二个约束以使列表正常工作,然后将重新查看我的继承结构。这些对象是 Entity Framework 的 POCO 实体,所以看起来我需要一个共同的祖先。

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


【解决方案1】:

以下应该这样做:

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
        }

    }

【讨论】:

  • 如果 MyType 和 MyOtherType 不兼容,那么您的 htmlhelper 的使用将无法编译,因为没有类型会同时满足您的约束。我认为您需要两个 html 助手,一个用于 MyType,一个用于 MyOtherType。然后通用参数 TProperty 就被废弃了。
  • @Burnzy: 看起来很有希望,但是我在expression.Compile().Invoke(model) 线上遇到了以下错误 - 无法从“object”转换为“TModel”并委托“System.Func' 有一些无效参数
  • @Maarten 我相信 TProperty 不会被显式定义,它将由表达式属性类型隐式定义。
  • @Terric 我相信你必须投它。查看较新的编辑。你在我编辑之前就发布了:)
  • @Burnzy:宾果游戏!是的,已经完成了,非常感谢!
【解决方案2】:

怎么样....

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 
        } 

    } 

【讨论】:

    猜你喜欢
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多