如何从对象列表创建MVC HtmlHelper表

我正在尝试创建一个特定的HtmlHelper表扩展,以减少我的视图中的意大利面条代码。

获取域对象列表我想显示一个表,它在使用域对象的属性作为列时更加智能。 另外,我想禁用一些属性作为列显示。 一个想法是用属性来装饰属性,告诉它不被显示。

希望这是有道理的,但到目前为止我到达的地方……

public static string MyTable(this HtmlHelper helper, string name, IList items, object tableAttributes) { if (items == null || items.Count == 0) return String.Empty; StringBuilder sb = new StringBuilder(); BuildTableHeader(sb, items[0].GetType()); //TODO: to be implemented... //foreach (var i in items) // BuildMyObjectTableRow(sb, i); TagBuilder builder = new TagBuilder("table"); builder.MergeAttributes(new RouteValueDictionary(tableAttributes)); builder.MergeAttribute("name", name); builder.InnerHtml = sb.ToString(); return builder.ToString(TagRenderMode.Normal); } private static void BuildTableHeader(StringBuilder sb, Type p) { sb.AppendLine(""); //some how here determine if this property should be shown or not //this could possibly come from an attribute defined on the property foreach (var property in p.GetProperties()) sb.AppendFormat("{0}", property.Name); sb.AppendLine(""); } //would be nice to do something like this below to determine what //should be shown in the table [TableBind(Include="Property1,Property2,Property3")] public partial class MyObject { ...properties are defined as Linq2Sql } 

所以我只是想知道是否有人对这个想法或任何替代方案有任何意见/建议?

到目前为止看起来不错,但Gil Fink可能已经为你完成了这项工作: http : //blogs.microsoft.co.il/blogs/gilf/archive/2009/01/13/extending-asp-net-mvc-的HtmlHelper-class.aspx

我强烈建议使用MvcContrib的Grid 。 如果您决定不这样做,至少可以看一下他们如何解决表生成界面问题。

经过大约一个小时的工作,我能够创造出我想要的东西。 我的解决方案是在域对象类上创建一个属性,指定哪些属性在我的表中可见。

基于MVC 1.0中的BindAttribute属性(查看源代码),我创建了一个TableProperty属性。

 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] public class TableProperty : Attribute { private string m_include; private string[] m_includeSplit; public TableProperty() { m_includeSplit = new string[0]; } public string Include { get { return (m_include ?? string.Empty); } set { m_include = value; m_includeSplit = value.Split(','); } } public bool IsPropertyAllowed(string propertyName) { return IsPropertyAllowed(propertyName, m_includeSplit); } internal static bool IsPropertyAllowed(string propertyName, string[] includeProperties) { return ((includeProperties == null) || (includeProperties.Length == 0)) || includeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase); } } 

这允许我用这个属性装饰我的域对象……

 [TableProperty(Include="Property1,Property2,Property3")] public partial class MyObject { ... 

然后在BuildTableHeader中我使用reflection来获取对象的属性,并将每个属性与允许的列表相匹配。

 private static void BuildTableHeader(StringBuilder sb, Type p) { sb.AppendLine(""); TableProperty tp = p.GetCustomAttributes(typeof(TableProperty), true)[0]; foreach (var property in p.GetProperties()) if (tp.IsPropertyAllowed(property.Name)) sb.AppendFormat("{0}", property.Name); 

请注意这个解决方案在我的小应用程序中对我有用,但是会更多地关注MvcContrib的Grid以获得更好的实现。