I’m quite new to both ASP.Net and MVC.
I got the following code in my master page:
<div id="main-menu" class="menu">
<%
var items = (IList<CompanyName.Framework.Web.MenuItem>)ViewData["MainMenu"];
if (items.Count > 0)
{
%><ul><%
foreach (var item in items)
{
if (!string.IsNullOrEmpty(item.RequiredRole) && !System.Threading.Thread.CurrentPrincipal.IsInRole(item.RequiredRole))
continue;
%><li><a href="<%= item.Uri %>"><%= item.Title %></a></li><%
}
%></ul><%
}
%>
</div>
Can I move the code to another file or refactor the code in any way?
edit:
My ApplicationController that all controllers derive:
public class ApplicationController : Controller
{
List<MenuItem> _mainMenu = new List<MenuItem>();
List<MenuItem> _contextMenu = new List<MenuItem>();
protected IList<MenuItem> MainMenu
{
get { return _mainMenu; }
}
protected IList<MenuItem> ContextMenu
{
get { return _contextMenu; }
}
protected string PageTitle { get; set; }
protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
ViewData["PageTitle"] = PageTitle;
ViewData["MainMenu"] = MainMenu;
ViewData["ContextMenu"] = ContextMenu;
base.OnResultExecuting(filterContext);
}
}
Here are a couple of suggestions:
Improvement number 1: use view models and strongly typed views instead of ViewData
and then in your view:
Still horrible and completely unreadable tag soup.
Improvement number 2: use editor/display templates:
In
~/Views/Home/DisplayTemplates/MenuItem.ascx:And then in your main view:
Improvement number 3: Avoid coding business rules in a view. So in your view model add a property:
so that your display template now looks like this:
Improvement number 4: Write a custom HTML helper to render this anchor because writing C# in a view is still ugly and untestable:
and finally your display template: