Creating reusable HTML view components using Razor in ASP.NET MVC

There are two ways to achieve the required functionality.

1. @helper

Create @helper which accepts whatever parameters you need plus a function (single object parameter, returns object):

@helper DefaultPanel(string panelTitle, Func<object, object> content)
{
    <div class="panel">
        <div class="panel-logo">
                <img src="https://stackoverflow.com/logo.png" />
            </div>
            <div class="panel-inner">
                <p class="panel-title">@panelTitle</p>
                <div class="panel-content">
                    @content(null)
                </div>
            </div>
    </div>
}

Usage:

@DefaultPanel("title",
@<div class="panel-content-inner">
    <p>Welcome back, please select from the following options</p>
    <a href="#">Profile</a>
    <a href="#">My Defails</a>
</div>
)

Your function may also accepts parameters, example here.

2. HtmlHelper extension method

Add the following code anywhere in your project:

namespace System.Web.Mvc
{
    public static class HtmlHelperExtensions
    {
        public static HtmlDefaultPanel DefaultPanel(this HtmlHelper html, string title)
        {
            html.ViewContext.Writer.Write(
            "<div class=\"panel\">" +
            "<div class=\"panel-inner\">" +
            "<p class=\"panel-title\">" + title + "</p>" +
            "<div class=\"panel-content\">"
            );

            return new HtmlDefaultPanel(html.ViewContext);
        }
    }

    public class HtmlDefaultPanel : IDisposable
    {
        private readonly ViewContext _viewContext;
        public HtmlDefaultPanel(ViewContext viewContext)
        {
            _viewContext = viewContext;
        }
        public void Dispose()
        {
            _viewContext.Writer.Write(
            "</div>" +
            "</div>" +
            "</div>"
            );
        }
    }
}

Usage:

@using (Html.DefaultPanel("title2"))
{
    <div class="panel-content-inner">
        <p>Welcome back, please select from the following options</p>
        <a href="#">Profile</a>
        <a href="#">My Defails</a>
    </div>
}

The extension method writes directly to the context. The trick is to return a disposable object, which Dispose method will be executed at the end of using block.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)