Df5b3718dcbe9055cc6672d8715fcf4f

I wanted to display list from my object:
user[x].Group[y].Name
I got some of code from here: http://blog.wekeroad.com/blog/asp-net-mvc-list-helper-extension-method/

I'm wondering if there is a better way.

public static string ToFormattedList<T>(this HtmlHelper helper, IList<T> objectList, ListType listType, Func<T, string> valueReturn)
{

    string outerListFormat = "";
    string listFormat = "";

    switch (listType)
    {
        case ListType.Ordered:
            outerListFormat = "<ol>{0}</ol>";
            listFormat = "<li>{0}</li>";
            break;
        case ListType.Unordered:
            outerListFormat = "<ul>{0}</ul>";
            listFormat = "<li>{0}</li>";
            break;
        case ListType.TableCell:
            outerListFormat = "{0}";
            listFormat = "<td>{0}</td>";
            break;
        default:
            break;
    }

    var sb = new StringBuilder();
    objectList.ForEach(item => sb.AppendFormat(listFormat, valueReturn(item)));
    return string.Format(outerListFormat, sb);
}

public enum ListType
{
    Ordered,
    Unordered,
    TableCell
}
Html.ToFormattedList(item.Groups, UiHelpers.ListType.Unordered, g => g.GroupName )

Refactorings

No refactoring yet !

F9a9ba6663645458aa8630157ed5e71e

Ants

January 26, 2010, January 26, 2010 06:13, permalink

No rating. Login to rate!

I don't get to do much ASP.NET MVC work, but I really subscribe to the philosophy it has of keeping the markup in as separate from the code as possible. My preference would be to go with the approach shown here:

http://haacked.com/archive/2008/05/03/code-based-repeater-for-asp.net-mvc.aspx

With the code above, I like the way a StringBuilder is used for efficiency, but all that lost when applying the formatting. How about something like:

public static string ToFormattedList<T>(IList<T> objectList, Func<T, string> valueReturn,
                                        string outerPrefix, string outerSuffix,
                                        string innerPrefix, string innerSuffix)
{
    var sb = new StringBuilder();

    sb.Append(outerPrefix);
    foreach(T item in objectList)
    {
        sb.Append(innerPrefix);
        sb.Append(valueReturn(item));
        sb.Append(innerSuffix);
    }
    sb.Append(outerSuffix);
    return sb.ToString();
}

public static string ToFormattedList<T>(this HtmlHelper helper, IList<T> objectList, 
                                        ListType listType, Func<T, string> valueReturn)
{
    switch (listType)
    {
    case ListType.Ordered:
        return ToFormattedList<T>(objectList, valueReturn, "<ol>", "</ol>", "<li>", "</li>");

    case ListType.Unordered:
        return ToFormattedList<T>(objectList, valueReturn, "<ul>", "</ul>", "<li>", "</li>");

    case ListType.TableCell:
        return ToFormattedList<T>(objectList, valueReturn, "", "", "<td>", "</td>");
    }
    return ToFormattedList<T>(objectList, valueReturn, "", "", "", "");
}

public enum ListType
{
    Ordered,
    Unordered,
    TableCell
}
Html.ToFormattedList(item.Groups, UiHelpers.ListType.Unordered, g => g.GroupName )
8a997df3c1179bfa2c4bfb706a4db611

Frank Alvarez

January 12, 2012, January 12, 2012 16:21, permalink

No rating. Login to rate!

If you prefer doing this using the new ASP.NET MVC Templated Razor Delegates. Here's my version:

public static class HtmlListExtensions
    {
        public enum ListType
        {
            Ordered,
            Unordered,
            TableCell
        }

        private class ListModel
        {
            public string FirstTag { get; set; }
            public string LastTag { get; set; }
            public string InnerFirstTag { get; set; }
            public string InnerLastTag { get; set; }
        }

        public static HelperResult ToFormattedList<T>(this HtmlHelper helper, List<T> collection,
                                                ListType listType, Func<T, HelperResult> template)
        {
            var model = new ListModel{FirstTag = "",LastTag = "",InnerFirstTag = "",InnerLastTag = ""};
            switch (listType)
            {
                case ListType.Ordered:
                    model.FirstTag = "<ol>";
                    model.LastTag = "</ol>";
                    model.InnerFirstTag = "<li>";
                    model.InnerLastTag = "</li>";
                    break;

                case ListType.Unordered:
                    model.FirstTag = "<ul>";
                    model.LastTag = "</ul>";
                    model.InnerFirstTag = "<li>";
                    model.InnerLastTag = "</li>";
                    break;
                case ListType.TableCell:
                    model.InnerFirstTag = "<td>";
                    model.InnerLastTag = "</td>";
                    break;
            }
            return new HelperResult(writer => ToFormattedList<T>(collection, template, writer, model));
        }


        private static void ToFormattedList<T>(IEnumerable<T> collection, Func<T, HelperResult> template, TextWriter writer, ListModel model)
        {
            writer.Write(model.FirstTag);
            foreach (T item in collection)
            {
                writer.Write(model.InnerFirstTag);
                writer.Write(template(item));
                writer.Write(model.InnerLastTag);
            }
            writer.Write(model.LastTag);
        }
    }
@Html.ToFormattedList(model.Groups, HtmlListExtensions.ListType.Unordered, @<span>@item.GroupName</span>)
8a997df3c1179bfa2c4bfb706a4db611

Frank Alvarez

January 12, 2012, January 12, 2012 16:21, permalink

No rating. Login to rate!

If you prefer doing this using the new ASP.NET MVC Templated Razor Delegates. Here's my version:

public static class HtmlListExtensions
    {
        public enum ListType
        {
            Ordered,
            Unordered,
            TableCell
        }

        private class ListModel
        {
            public string FirstTag { get; set; }
            public string LastTag { get; set; }
            public string InnerFirstTag { get; set; }
            public string InnerLastTag { get; set; }
        }

        public static HelperResult ToFormattedList<T>(this HtmlHelper helper, List<T> collection,
                                                ListType listType, Func<T, HelperResult> template)
        {
            var model = new ListModel{FirstTag = "",LastTag = "",InnerFirstTag = "",InnerLastTag = ""};
            switch (listType)
            {
                case ListType.Ordered:
                    model.FirstTag = "<ol>";
                    model.LastTag = "</ol>";
                    model.InnerFirstTag = "<li>";
                    model.InnerLastTag = "</li>";
                    break;

                case ListType.Unordered:
                    model.FirstTag = "<ul>";
                    model.LastTag = "</ul>";
                    model.InnerFirstTag = "<li>";
                    model.InnerLastTag = "</li>";
                    break;
                case ListType.TableCell:
                    model.InnerFirstTag = "<td>";
                    model.InnerLastTag = "</td>";
                    break;
            }
            return new HelperResult(writer => ToFormattedList<T>(collection, template, writer, model));
        }


        private static void ToFormattedList<T>(IEnumerable<T> collection, Func<T, HelperResult> template, TextWriter writer, ListModel model)
        {
            writer.Write(model.FirstTag);
            foreach (T item in collection)
            {
                writer.Write(model.InnerFirstTag);
                writer.Write(template(item));
                writer.Write(model.InnerLastTag);
            }
            writer.Write(model.LastTag);
        }
    }
@Html.ToFormattedList(model.Groups, HtmlListExtensions.ListType.Unordered, @<span>@item.GroupName</span>)

Your refactoring





Format Copy from initial code

or Cancel