While refactoring a "menu" page, I broke a single view into multiple views. And it worked when I ran the project locally. However, once I checked-in my code and deployed it to our development environment, it was no longer working.
Original View:
@model Domain.ViewModel
@{
ViewBag.Title = "TabbedIndex";
}
<div class="row" style="padding-top:20px">
@foreach(var group in Model.MenuGroups)
{
<div class="col-md-3 menu-group">
@{
switch(group.IconType)
{
case "image":
<span class="menu-group-icon" style="background-image:url(@group.IconLocation)"></span>
break;
case "glyphicon":
<span class="glyphicon glyphicon-@group.IconLocation"></span>
break;
}
}
<h3>@group.Text</h3>
<ul>
@foreach (var item in group.Items)
{
<li>
@if (item.Active)
{
<a href="@item.URL">@item.Text</a>
}
else
{
@item.Text
}
</li>
}
</ul>
</div>
}
</div>
So, I tried to break it up. I needed to add a Row for the Groups to be a part of. So, I ended up with this.
StartMenu.cshtml
@model Domain.Menu
@{
ViewBag.Title = "TabbedIndex";
}
@foreach (var row in Model.MenuRows) { @Html.Partial("MenuRow", row); }
MenuRow.cshtml
@model Domain.MenuRow
<div class="row" style="padding-top:20px">
@foreach (var group in Model.Groups) { @Html.Partial("MenuGroup", group); }
</div>
MenuGroup.cshtml
@model Domain.MenuGroup
<div class="col-md-3 menu-group">
@{
switch (Model.IconType)
{
case "image":
<span class="menu-group-icon" style="background-image:url(@Model.IconLocation)"></span>
break;
case "glyphicon":
<span class="glyphicon glyphicon-@Model.IconLocation"></span>
break;
}
<h3>@Model.Text</h3>
<ul>
@foreach (var item in Model.Items) { @Html.Partial("MenuItem", item); }
</ul>
}
</div>
MenuItem.cshtml
@model Domain.MenuItem
<li>
@if (Model.Active)
{
<a href="@Model.URL"
@Html.Raw(string.IsNullOrWhiteSpace(Model.Description) ? "" : "data-toggle='tooltip'")
title="@Model.Description">@Model.Text</a>
}
else { @Model.Text; }
</li>
All of this is called from the HomeController Menu function. All views are stored in the Views/Home folder. Here is the Menu function:
public ActionResult Menu()
{
ViewData.Add("TabName", "Admin Home");
return View("StartMenu", new Menu.StartMenu());
}
All of this worked locally. I ran it, the menu came up, I was able to click on the links and go to the right pages. However, once it was deployed to our Dev environment, the Menu errored out. And the error we were getting was:
System.InvalidOperationException: The partial view 'MenuRow' was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/Home/MenuRow.cshtml
I tried relative paths:
~/Views/Home/MenuRow.cshtml
I originally tried them in their own StartMenu folder:
../StartMenu/MenuRow
I tried RenderPartial instead of Partial.
At one point, I did not have the "@" in front of the Html.RenderPartial, but when I changed it to Html.Partial, I had to add it.
I don't believe the partial view name HAS to have an underscore (I believe it is just a naming convention).
If you could help me figure this out, I would truly appreciate it. I cannot for the life of me figure out why it would work locally but not on the development environment. Is it possible that the Development environment has a different view engine that what I have locally? And if so, how would I check that?
I have since combined them back into a single view and it works now. However, I would like to eventually break these out again to keep the files small.