One hidden gem of Razor View Engine is the declarative helper syntax. With this syntax, we can create helper components that are stored as .cshtml files, and enable reusability of view code. The name of the syntax might sound familiar and it is since it reminds the HtmlHelper
class that was provided as part of MVC 1. In this post, I’ll explain the Razor helper syntax and discuss why it sounds familiar to HtmlHelper
.
@helper Syntax and The HtmlHelper Class
When you want to encapsulate a view code and make it reusable, you’ll probably create an extension method to extend the HtmlHelper
class. By doing so, all you’ll need to do when that view code is needed is to call the @Html
with the method name you’ve created. Here is an example of an HtmlHelper
method for building a simple HTML5 video tag:
public static class HtmlHelpers
{
public static MvcHtmlString Video(this HtmlHelper helper, string id, string sourceUrl, bool controls)
{
TagBuilder builder = new TagBuilder("video");
builder.MergeAttribute("id", id);
builder.MergeAttribute("src", sourceUrl);
if (controls)
{
builder.MergeAttribute("controls", "controls");
}
return new MvcHtmlString(builder.ToString(TagRenderMode.Normal));
}
}
and integrating it inside a view:
@{
ViewBag.Title = "Home Page";
}
@using AsyncMVC
<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit
<a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>
@Html.Video("prolog", Url.Content("~/Prolog.mov"), true)
Razor view engine makes it even easier. You can use the @helper
syntax and create an inline helper code inside your view (without the creation of an extension method) or make it reusable as a different cshtml file. How does it work? Let's take a look at an inline example:
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit
<a href="http://asp.net/mvc" title="ASP.NET MVC Website">http:
</p>
@helper Video(string id, string sourceUrl, bool controls)
{
TagBuilder builder = new TagBuilder("video");
builder.MergeAttribute("id", id);
builder.MergeAttribute("src", sourceUrl);
if (controls)
{
builder.MergeAttribute("controls", "controls");
}
var video = new MvcHtmlString(builder.ToString());
@video
}
@Video("prolog", Url.Content("~/Prolog.mov"), true)
As you can see, most of the code that was in the HtmlHelper
was transferred to the view with a little change of using a variable for the returned type. This inline code makes it easier to call the method (no HtmlHelper
class in the middle) and we don’t need to create extension methods in our application. On the other hand, using inline code isn’t reusable outside the scope of the view so what can we do about that? We can separate the helper block to a different cshtml file and use it in our other application views.
Separating Helpers into Their Own File
In order to put Razor helpers in their own cshtml file, you’ll have to add the App_Code directory to your MVC application. In the application project, create a new directory with the name App_Code
. ASP.NET considers this directory name as special directory name and therefore it will get a special icon. After creating the directory, add a View (cshtml file) into it and call it Helpers (for example):
In the created cshtml file, drop the code of the helper from the previous code block and add a using
statement for System.Web.Mvc
(which is needed for the TagBuilder
and MvcHtmlString
classes):
@using System.Web.Mvc
@helper Video(string id, string sourceUrl, bool controls)
{
TagBuilder builder = new TagBuilder("video");
builder.MergeAttribute("id", id);
builder.MergeAttribute("src", sourceUrl);
if (controls)
{
builder.MergeAttribute("controls", "controls");
}
var video = new MvcHtmlString(builder.ToString());
@video
}
After building the solution, now the previous view can be used as follows:
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">
http:
</p>
@Helpers.Video("prolog", Url.Content("~/Prolog.mov"), true)
Now the video helper is reusable and you can use it in all the views in your application.
Summary
The Razor helper syntax can be very usable and can help you to create helpers without the need for extension methods. On the other hand, that doesn’t mean that the HtmlHelper
extensions don’t have benefits. Since you can place them in different class libraries, you can reuse their code in other applications. With the helper syntax, you’ll have to create the App_Code directory and move the helper files to other applications. The choice is yours so pick what you think is more suited for your implementation.