In the View Layer, there are two styles of HTML markup shown. The first that we will show is NavigationPanel.ascx. It is a partial view. The Model object for this page is of type Cartella.Models.MenuPanel as can be seen by the Inherits attribute.

CopyC#
<%@ Import Namespace="Cartella.Models" %>
<%@ Import Namespace="Cartella.Models.EditForm" %>
<%@ Import Namespace="Cartella.Classes" %>
<%@ Import Namespace="Cartella.Interfaces" %>
<%@ Import Namespace="Cartella.Support" %>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Cartella.Models.MenuPanel>" %>
<%    
    if (Model != null)
    {
        if (!Model.Hidden)
        {
            bool isOpen = Model.Selected;
            string panelID = Model.ID;
            string title = Model.Title;
%>
<div dojotype="dijit.layout.AccordionPane" title="<%= title%>" selected="<% = isOpen %>"
    id="categoryMenu_<%=panelID %>">
    <div class="content border postList borderBottom">
        <%
            Model.MenuItems.Each((item) =>
            {
                string classStr = (item.Selected) ?
                    "selected" : "";

                string widgetType = "igx.Cartella.widget.FolioModuleNavItem_" + title.Trim();

                object attributes = new
                {
                    @class = classStr,
                    @dojoType = widgetType
                };

                var attrDict = attributes.ToDictionary();

                //append additional attributes from menu item definition, on top of class str and dojoType attributes
                if (item.Attributes != null)
                {
                    item.Attributes.Each((entry) =>
                    {
                        attrDict.Add(entry.Key, entry.Value);
                    });
                }

                using (Html.BeginCustomTag("p", attrDict))
                {
        %>
        <a href="<%=item.Url %>">
            <%=item.Label%>
            (<span dojoattachpoint="[<%=widgetType%>]countNode"><%=item.Count%></span>) </a>
        <%
                }
            });
        %>
    </div>
</div>
<%
        }
    } 
%>

This is similar to traditional ASP code with instances of <% %> marker pairs separating HTML and server-side code. The resulting code can be convoluted and difficult to maintain.

Using the HTML extension methods in MVC provides an alternative to generating raw HTML. For example

CopyC#
string classStr = (item.Selected) ?
                    "selected" : "";

                string widgetType = "igx.Cartella.widget.FolioModuleNavItem_" + title.Trim();

                object attributes = new
                {
                    @class = classStr,
                    @dojoType = widgetType
                };

                var attrDict = attributes.ToDictionary();

                //append additional attributes from menu item definition, on top of class str and dojoType attributes
                if (item.Attributes != null)
                {
                    item.Attributes.Each((entry) =>
                    {
                        attrDict.Add(entry.Key, entry.Value);
                    });
                }

                using (Html.BeginCustomTag("p", attrDict))
                {
                    …… …… 
                }

The result is a paragraph tag with a dynamic list of attributes. The traditional coding would be:

CopyC#
string pAttributes = .....
        %>
        <p <%=pAttributes %>>
            ...
        </p>

This method is more abstract. The result is a ‘p’ tag with attributes. Using the using (Html.BeginCustomTag("p", attrDict)), only a dictionary is needed. This results in cleaner code. Note also that the ‘p’ tag is now closed by the ‘}’.

This approach sacrifices HTML validation but gains the benefit of clean, easy to maintain code.

Using TagBuilder

TagBuilder can generate clean HTML code, but the result will not immediately be seen as HTML. Ingeniux recommends using TagBuilder in two situations:

  1. When the number of attributes varies depending on server-side values

  2. When the attributes are case sensitive (i.e. dojo widget markups)