基于MVC3 razor的htmlhelper,基于模型的lambda字段表达式

时间:2011-06-05 15:55:13

标签: asp.net-mvc-3 lambda grid expression

我在MVC中创建一个流畅的HtmlHelper - 创建一个基于HTML的网格。 我知道mvc contrib和WebGrid - 但我正在制作我自己的并且有一个特定的问题:

我必须输入:

@Html.DSGridFor().AddColumn(x=>x.FirstOrDefault().Message)

但我希望能够输入:

@Html.DSGridFor().AddColumn(x=>x.Message)

当我从@Html.DSGridFor()开始时调用的代码 - 接受基于页面的模型。

public static DSGridHelper<TModel> DSGridFor<TModel>(this HtmlHelper<TModel> html)
{
   return new DSGridHelper<TModel>(html);
}

然后在类DSGridHelper中我有这个:

public DSGridHelper<TModel> AddColumn(Expression<Func<TModel, dynamic>> property, string HeaderText = null)
        {
            string ColumnName = (property.Body as MemberExpression).Member.Name;

            DSGridColumn DSGC = new DSGridColumn();
            DSGC.ColumnName = ColumnName;
            DSGC.HeaderText = HeaderText ?? ColumnName;
            DSColumnList.Add(DSGC);

            return this;
        }

public List<DSGridColumn> DSColumnList { get; set; }

目前的列类非常基础:

  public class DSGridColumn
    {
        public DSGridColumn()
        {

        }

        public string ColumnName { get; set; }
        public string HeaderText { get; set; }

    }

我可以使用基于字符串的列名来使这段代码正常工作,但我希望razor页面中的声明代码格式简单并且强类型化。目前我必须输入x =&gt; x.First()。消息但我真的只需要x =&gt; x.Message来识别列。

我感谢任何帮助。

更新

感谢Justin,我现在可以提供我/我们的代码。

查看:

@(Html.DSGridFor3().AddColumn(x => x.Message)
                   .AddColumn(x => x.Host)
                   .ToMvcString())

HTML Helper电话:

public static DSGridHelper3<T> DSGridFor3<T>(this HtmlHelper<IEnumerable<T>> htmlHelper)
{
         return new DSGridHelper3<T>(htmlHelper);
}

返回课程:

public class DSGridHelper3<T>
    {
        private HtmlHelper _htmlHelper;
        //private IEnumerable<T> _dataList;
        public List<DSGridColumn> DSColumnList { get; set; }

        public DSGridHelper3(HtmlHelper<IEnumerable<T>> htmlHelper)
        {
            _htmlHelper = htmlHelper;
           // _dataList = htmlHelper.ViewData.Model;
            DSColumnList = new List<DSGridColumn>();
        }

        public DSGridHelper3<T> AddColumn(Expression<Func<T, object>> property)
        {
            string columnName = (property.Body as MemberExpression).Member.Name;
            DSGridColumn DSGC = new DSGridColumn();
            DSGC.ColumnName = columnName;
            DSGC.HeaderText = columnName;
            DSColumnList.Add(DSGC);

            return this;
        }

        public MvcHtmlString ToMvcString()
        {
            sb.Append("<table>");
            sb.Append("<tr>");
            sb.Append("<td>");
            sb.Append("hello world within a table");
            sb.Append(@"</td>");
            sb.Append("<td>");
            sb.Append("hello world within a table");
            sb.Append(@"</td>");
            sb.Append(@"</tr>");
            sb.Append(@"</table>");


            return new MvcHtmlString(sb.ToString());

        }
    }

更新2

如果你想手动插入另一种类型(可能是因为你要从ViewData而不是页面模型中获取少量的表数据),那么这里有更多的代码:

查看:

@(Html.DSGridFor3<DanSoftware.MVC.Areas.Errors.Code.ELMAH_Error>().AddColumn(x => x.Message).ToMvcString();)

DSGridHelper的替代签名...帮助

public static DSGridHelper3<T> DSGridFor3<T>(this HtmlHelper htmlHelper)
        {
            return new DSGridHelper3<T>(htmlHelper);
        }

其他构造函数:

public DSGridHelper3(HtmlHelper htmlHelper)
        {
            _htmlHelper = htmlHelper;
            // _dataList = htmlHelper.ViewData.Model;
            DSColumnList = new List<DSGridColumn>();
        }

希望这有助于某人并感谢贾斯汀!

1 个答案:

答案 0 :(得分:2)

我没有和我一起使用Visual Studio,但是我会对此进行一次尝试......

我会在您的DsGridFor方法或AddColumn方法中将集合作为数据类型。这将允许您从集合中发送强类型参数。假设您想要一个给定集合AddColumn的泛型方法,可以访问类属性和集合方法,它看起来像这样(只是一个例子):

    public static DSGridHelper<T> AddColumn<T>(this HtmlHelper<IEnumerable<T>> htmlHelper, Expression<Func<T, object>> property) where T : class
    {
        string columnName = (property.Body as MemberExpression).Member.Name;

        DSGridColumn DSGC = new DSGridColumn();
        DSGC.ColumnName = ColumnName;
        DSGC.HeaderText = HeaderText ?? ColumnName;
        DSColumnList.Add(DSGC);

        return this;
    }

根据您的情况,为了新建一个DsGridHelper类,我可以先显式设置模型类型,然后在我去的时候添加重载:

    public static DSGridHelper<T> DSGridFor<T>(this HtmlHelper<IEnumerable<T>> htmlHelper) where T : class
    {
        return new DSGridHelper<T>(htmlHelper);
    }

然后我的DsGridHelper看起来像这样:

public class DsGridHelper<T>
{
    private HtmlHelper _htmlHelper;
    private IEnumerable<T> _dataList;

    public DsGridHelper(HtmlHelper<IEnumerable<T>> htmlHelper)
    {
        _htmlHelper = htmlHelper;
        _dataList = htmlHelper.ViewData.Model;
    }

    public DsGridHelper<T> AddColumn(Expression<Func<T, object>> property)
    {
        string columnName = (property.Body as MemberExpression).Member.Name;
        DSGridColumn DSGC = new DSGridColumn();
        DSGC.ColumnName = ColumnName;
        DSGC.HeaderText = HeaderText ?? ColumnName;
        DSColumnList.Add(DSGC);

        return this;
    }
}