Как создать таблицу MVC HtmlHelper из списка объектов

Я пытаюсь создать определенное расширение таблицы HtmlHelper, чтобы уменьшить код спагетти на мой взгляд.

принимая список объектов домена, я хотел бы отобразить таблицу, которая немного более умна в использовании свойств объекта домена в качестве столбцов. Кроме того, я хотел бы отключить отображение некоторых свойств в виде столбцов. Идея состояла бы в том, чтобы украсить свойства атрибутами, которые говорят ему не отображаться.

надеюсь, это имеет смысл, но вот до чего я дошел...

public static string MyTable(this HtmlHelper helper, string name, 
    IList<MyObject> 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("<tr>");

    //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("<th>{0}</th>", property.Name);

    sb.AppendLine("</tr>");
}

//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
}

поэтому мне просто интересно, есть ли у кого-нибудь мнения/предложения по этой идее или какие-либо альтернативы?

3 ответов


выглядит хорошо до сих пор, но Гил Финк, возможно, уже сделал работу для вас здесь: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/01/13/extending-asp-net-mvc-htmlhelper-class.aspx


Я настоятельно рекомендую использовать MvcContrib это решетки. Если вы решите не делать этого, по крайней мере, вы можете взглянуть на то, как они решили проблему интерфейса генерации таблиц.


примерно через час работы я смог создать то, что хотел. Мое решение состояло в создании атрибута в классе объектов домена, который указывал, какие свойства были видны в моей таблице.

на основе атрибута BindAttribute в MVC 1.0 (взглянув на исходный код), я создал атрибут 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<string>(propertyName, StringComparer.OrdinalIgnoreCase);
    }
}

Это позволило мне украсить мой объект домена с этим атрибутом...

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

затем внутри BuildTableHeader я использовал отражение, чтобы получить свойства объекта и сопоставить каждое свойство с разрешенным списком.

private static void BuildTableHeader(StringBuilder sb, Type p)
{
    sb.AppendLine("<tr>");

    TableProperty tp = p.GetCustomAttributes(typeof(TableProperty), true)[0];

    foreach (var property in p.GetProperties())
        if (tp.IsPropertyAllowed(property.Name))
            sb.AppendFormat("<th>{0}</th>", property.Name);

обратите внимание, что это решение работало для меня в моем маленьком приложении, однако будет больше смотреть на сетку MvcContrib для лучшей реализации.