I am in the process of creating a prototype project using MVC 3 and I have come across a situation which I can't seem to find an answer for and it seems like I might be approaching the problem the wrong way.
A quick overview of my project; it is based on the MVC template you get with Visual Studio and I use the links (tabs) on the supplied _Layout view to access some of my other views. One of these links opens a second partial view that again contains links for more views (admin specific. hence the split). The problem I am having is that I can't seem to display views with the @RenderBody in the second partial view, which I understand is because you can't have more than one @RenderBody in a completed HTML file, which makes sense.
So my question is, how can I display the views in this manner? Also, probably more importantly, is this the correct way to achieve this 'sub menu' system I am trying for or is there a better way to achieve this?
Here is the relevant parts of the views, first is the 'main' _Layout file:
<body>
<div class="page">
<header>
<div id="title">
<h1>Test App</h1>
</div>
<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
@if (User.Identity.IsAuthenticated)
{
<li>@Html.ActionLink("Contracts", "List", "Contract", new { user=User.Identity.Name, page=1 }, null)</li>
}
@if (User.IsInRole("Administrator"))
{
<li id="admin">@Html.ActionLink("Administration", "Administration", "Home")</li>
}
</ul>
</nav>
</header>
<section id="main">
@RenderBody()
</section>
<footer>
</footer>
</div>
</body>
When clicking the <li id="admin">@Html.ActionLink("Administration", "Administration", "Home")</li> link, then the Home controller return the second partial view shown below:
<header>
<div id="admintitle">
<h1>Administration</h1>
</div>
</header>
<body>
<div id="div-1a">
<nav>
<ul id="adminmenu">
<li>@Html.ActionLink("Contact", "List", "Contact")</li>
<li>@Html.ActionLink("Home", "Index", "Home")</li>
</ul>
</nav>
</div>
<div id="div-1c">
<h1>Test</h1>
</div>
<section id="adminmain">
@RenderBody()
</section>
</body>
When I try and run the code, it fails due to the second @RenderBody, which is understandable.
If you need any more information, then please let me know.
Thanks very much.
You can not use @RenderBody() multiple times. One @RenderBody() in your main _Layout file is fair enough. In your second view use instead @RenderPartial() or @RenderAction.
UPDATE (based on first comment)
Let's say you want to render /Administrator/TheAction, so you will call
@{
Html.RenderAction("TheAction", "Administrator");
}
TheAction action will look like this:
public PartialViewResult TheAction() {
return PartialView();
}
And it will render the view in ~/Views/Administrator/TheAction.cshtml right inside the place from which you called the RenderAction().
The importance is that it does not accomplish another @RenderBody. As you can see in TheAction() example, you are returning PartialViewResult, which does not have any @RenderBody() helper.
Convert
From
<section id="adminmain">
@RenderBody()
</section>
To
<div id="adminmain"></div>
From
@Html.ActionLink("Contact", "List", "Contact")
To
@Ajax.ActionLink("Contact", "List", "Contact", new AjaxOptions { UpdateTargetId = "adminmain" })
And in ContactController List action return PartialView() instead of 'View()'.
Do not forget to include jquery.unobtrusive-ajax in your view to make Ajax work.
And before all read Roman's Answer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With