Html.ForEach in Razor

Many people write ForEach extension methods for MVC WebForms views, which take a sequence and a delegate to turn each item in the sequence into HTML.

For example:

public static void ForEach<T>(this HtmlHelper html,
                              IEnumerable<T> set, 
                              Action<T> htmlWriter) {
    foreach (var item in set) {
        htmlWriter(item);
    }
}

(The unused html parameter allows it to be called as an extension method like other HTML helpers)

This code can be called like this:

<ul>
    <% Html.ForEach(
            Enumerable.Range(1, 10),
            item => { %> <li><%= item %></li> <% }
    ); %>
</ul>

This code creates a lambda expression that writes markup to the page’s response stream by ending the code block inside the lambda body. Neither the lambda expression nor the ForEach helper itself return anything; they both write directly to the response.

The List<T>.ForEach method can be called exactly the same way.

In Razor views, this method cannot easily be called directly, since Razor pages cannot put markup inside of expressions.  You can use a workaround by creating an inline helper and calling it immediately, but it would be better to rewrite the ForEach method to take an inline helper directly.

The naïve way to do that is like this:

public static IHtmlString ForEachSimple<T>(
        this HtmlHelper html,
        IEnumerable<T> set,
        Func<T, HelperResult> htmlCreator
    ) {
    return new HtmlString(String.Concat(set.Select(htmlCreator)));
}

The htmlCreator delegate, which can be passed as an inline helper, returns a HelperResult object containing the markup generated for an item.

This code uses LINQ to call htmlCreator on each item in the set (the Select call), then calls String.Concat to combine them all into one giant string.  (String.Concat will call ToString on each HelperResult, which will return the generated markup)  We could also call String.Join to put a separator, such as a newline, between every two items.

Finally, it returns an HtmlString to prevent Razor from escaping the returned HTML.

It’s equivalent to the following code using a StringBuilder (this is what String.Concat does internally)

var builder = new StringBuilder();
foreach (var item in set) {
    HelperResult result = htmlCreator(item);
    builder.Append(result.ToString());
}
return new HtmlString(builder.ToString());

This method can be called like this:

<ul>
    @Html.ForEachSimple(
        Enumerable.Range(1, 10),
        @<li>@item</li>
    );
</ul>

The problem with this approach is that it combines all of the content into a giant string.  If there are a large number of items, or if each item will have a large amount of markup, this can become (a little bit) slow.  It would be better to write each item directly to the caller’s response stream, without assembling any giant strings.  This is where HelperResult comes in.

The HelperResult class allows its caller to pass a TextWriter to the WriteTo method, and the helper delegate will write directly to this TextWriter.  I can take advantage of this to write a ForEach extension that doesn’t build any strings, by returning a HelperResult instead of a regular IHtmlString.

public static HelperResult ForEachFast<T>(
        this HtmlHelper html,
        IEnumerable<T> set,
        Func<T, HelperResult> htmlCreator
    ) {
    return new HelperResult(tw => {
        foreach (var item in set) {
            htmlCreator(item).WriteTo(tw);
        }
    });
}
This version creates a HelperResult with a delegate that writes each of its items in turn to the TextWriter.

207 comments:

«Oldest   ‹Older   201 – 207 of 207   Newer›   Newest»

Thank you for providing this content. I appreciate the time and effort that you have put into creating it.
Clonko Yoga Cushions are offered in the market for boosting your yoga session enjoying incomparable comfort and support.

Visit Us -
Online Buy Meditation Pillow
Online Buy Yoga Cushion
Online Buy Yoga Pillow Bolster

As a prominent Zinc Trim Button Manufacturers, Swadeshi Button specializes in creating trims that offer aesthetic appeal and functional durability. Zinc trims add an elegant touch to clothing and accessories while enhancing the overall design. These trims come in various finishes, from polished to matte, ensuring they complement any garment or fabric style.

Hello, I am Looking the Your Website. This is the Very Good blogging website.
Amongst all those manufacturers that provide a wide range of Cork Foam Sheets in the market, Fusion Foams has positioned itself as the premium quality brand. Specially designed in detail, these sheets are highly stable, portable, and excellent thermal insulators required for several uses.

Visit Us -
Online Sale Cork Foam Roll Sheet
High-Quality Cork Sheet Supplier
Cork Foam Sheet Wholesale Supplier

For university accounting tasks, Assignment help Canberra provides precise, affordable, and timely assistance tailored to academic guidelines and aimed at ensuring student success.

Contact us today to explore our Home Mortgage UAE solutions and discover how our tailored Mtg Loans from a trusted Home Loans Provider in UAE can make your journey to homeownership seamless. With Money Hub UAE, securing your future starts with a conversation.

As a prominent Zinc Alloy Button Manufacturers, Swadeshi Button takes pride in offering zinc alloy buttons that are durable and highly customizable. Zinc alloy buttons are an excellent choice for premium garments due to their ability to withstand wear and tear while maintaining a polished look. These buttons are available in various shapes, sizes, and designs, allowing garment manufacturers to select the perfect match for their clothing lines.

A unique daycare in Panchkula, Boss Baby Club is committed to the holistic development of infants, toddlers, and children. In addition to providing complete and half-day care, preschool development, and a calm café for working women, we offer comprehensive interventions for milestone delays and a nurturing environment for families.

«Oldest ‹Older   201 – 207 of 207   Newer› Newest»

Post a Comment