I will try to show you a basic feature of ASP.NET MVC, creating custom HTML Helpers. We can reduce the amount of logic in view pages (razor or asp.net –aspx- pages) by extracting logic code as method.
HTML Helper methods are nothing more than methods that are returning string. If you want to write your own Html Helper method you have to write extension methods for HtmlHelper class. ASP.NET MVC Framework itself contains extension methods for HtmlHelper class to have well structured helper methods separation. ASP.NET MVC Framework Html Helper extension methods are located underSystem.Web.Mvc.Html namespace.
Razor pages uses System.Web.Mvc.WebViewPage type as base class. Razor pages automatically inherits from this type, If you want to see the configuration or if you want to replace it with your base class you should check web.config file in your ASP.NET MVC project. This subject is not in this article’s context but if you want to use your own base class, you can create a new class which inherits from WebViewPage and you can edit web.config file with your type name.
I mentioned that Html Helper methods are extension methods for HtmlHelper classes (one is generic, one is plain old class). So, we can write extension methods to use them inside Razor pages but how does it happen?
As you can see from above screenshot WebViewPage has a property named Html and this property type is System.Web.Mvc.HtmlHelper<T>.
And we can access this type and it’s member from Razor pages. (see below)
It seems we can add our extension methods and access that methods from Razor page markup. Let’s create our first extension methods. You can add a new class file and write your own extension method, there is no difference than normal C# extension methods.
I created a file named HtmlHelperExtensions.cs and added two basic HTML Helper method.
using System.Web.Mvc; namespace MvcHtmlHelpers { public static class HtmlHelperExtensions { private const string Nbsp = " "; private const string SelectedAttribute = " selected='selected'"; public static MvcHtmlString NbspIfEmpty(this HtmlHelper helper, string value) { return new MvcHtmlString(string.IsNullOrEmpty(value) ? Nbsp : value); } public static MvcHtmlString SelectedIfMatch(this HtmlHelper helper, object expected, object actual) { return new MvcHtmlString(Equals(expected, actual) ? SelectedAttribute : string.Empty); } } }
Two extesion methods, one is NbspIfEmpty, it checks the given value and if it’s empty returns , if it is not returns the given value. Second one is return selected attribute if criteria matches.
Let’s try to use this Html helpers methods from your Razor page. It will not work because we need to add our HTML Helper class to the Razor pages. It is same thing to adding a “using” statement to C# classes to use extension methods. Open your web.config file and add namespace of your new class which contains your extension methods.
<system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="MvcHtmlHelpers" /> </namespaces> </pages> </system.web.webPages.razor>
I want to show using of second HTML Helper. First select element contains and embedded if statement inside markup which doesn’t seem a good. Right?
<select> @foreach (var item in ViewBag.Items) { <option@if (item.ItemName==ViewBag.SelectedItem) { @MvcHtmlString.Create(" selected='selected'") }>@item.ItemName</option> } </select>
If we use our HTML Helper methods to make option element selected markup code seems better. (ViewBag.SelectedItem is an dynamic data for this sample Razor page and comes from controller. If item.ItemName equals this value option element will be selected.
<select> @foreach (var item in ViewBag.Items) { <[email protected]((string)ViewBag.SelectedItem,(string)item.ItemName)>@item.ItemName</option> } </select>
This is a very basic sample for HTML Helpers but you should look for possibilities of extract your logic from Razor pages to HTML Helpers.