Advertisement
Advertisement

Razor is a great way to create views with ASP.NET MVC. One feature I use quite often are custom helpers. Instead of duplicating the same few lines of markup I simply create a reusable helper to generate HTML.

MVC4_Logo

For example, you could create a helper to do something simple like render out a series of values…

Advertisement
@helper tabs(params Tab[] tabs) {
<ul>
@foreach(var tab in tabs) {
<li><a href="@tab.Url" >@tab.Text</a></li>
}
</ul>
}

Then use the helper by providing the parameters it needs…

@tabs(
new Tab { Text = "Google.com", Url = "https://google.com" },
new Tab { Text = "Hugoware.net", Url = "https://hugoware.net" },
new Tab { Text = "LosTechies.com", Url = "https://lostechies.com" })

This works pretty well for the most part but it is pretty limited in what it can do. Lets look at another approach.

Providing A ‘Template’

In the previous example values were passed into the helper and used to generate the markup required. This time, the helper accepts slightly different arguments that will allow a bit more control.

@helper dialog(string title, 
Func<object, object> content) {
<div class="dialog-box" >
<h3>@title</h3>
<div class="dialog-box-content" >
@content(null)
</div>
</div>
}

This example uses a simple lambda (Func<object, object>) as an argument to provide markup to render. This allows the Razor block (@<text>…</text>) to be passed in as an argument for the helper.

@dialog("User Status", 
@<strong>User is offline!</strong>
)

Now, the content is generated by an external source!

Using Types With Your Templates

So far the examples have used Func<object,object> as a template argument and then invoked the method with null as the argument. As it turns out, not only can you provide a value for that argument, if the argument type for the Func<…> is provided then it can be used from within a template.

@helper user_status(IEnumerable<User> users, 
Func<User, object> online,
Func<User, object> offline) {

<div class="user-status-list" >
<div class="user-status" >
@foreach(var user in users) {
<h3>@user.Username</h3>

if (user.IsOnline) { @online(user); }
else { @offline(user); }
}
</div>
</div>
}

The helper above passes each User into the correct template. Now, a User can be referenced by using item from within the template.

@user_status(users, 

online:@<div class="user-online" >
User @item.Username is online!
</div>,

offline: @<div class="user-offline" >
User @item.Username is offline!
<a href="#" >Send a message!</a>
</div>
)

Now, the contents of each template is unique to the User that was provided!

Advertisement

By Enrico

My greatest passion is technology. I am interested in multiple fields and I have a lot of experience in software design and development. I started professional development when I was 6 years. Today I am a strong full-stack .NET developer (C#, Xamarin, Azure)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.