I have some simple <header> stuff in the file Shared/_Header.cshtml.
My Shared/_Layout.cshtml inserts that code by calling
@Html.Partial("_Header")
This worked fine so far.
Now I have some views that, in addition to the normal output via the @RenderBody(), should also add some icons in a specific place in the header.
I use@RenderSection()in a couple of my views, to create a sidebar, etc.
Now my idea was to create a section within my view (e.g Home/Details.cshtml) and add a RenderSection call to the _Header. The Layout would call the Header, and header in turn would see if the section existed and call it.
However that doesn't seem to work. I get the following error/exception:
The file "~/Views/Shared/_Header.cshtml" cannot be requested directly because it calls the "RenderSection" method.
Where lies my error? I know I can "nest" a partial call inside a section just fine. This code works just fine to tell the layout what file to use for a sidebar:
@section Sidebar{
@Html.Partial("_SidebarDetails")
}
Does it not work the other way round?
I need way to define a block of HTML inside a view that is then put into a predefined place inside of a partial that is called by the layout.
Please help me understand how to do this.
If a view contains a RenderSection it is considered to be a layout page and cannot be rendered directly. See this question for more info: The file "~/Views/Position/Edit.cshtml" cannot be requested directly because it calls the "RenderSection" method
The easiest solution is to merge the partial view into the layout particularly if _Header.cshtml is only included on the layout page.
Another option is to override the header view with a custom header when needed.
In your layout page:
@if (IsSectionDefined("Header"))
{
RenderSection("Header");
}
else
{
@Html.Partial("_Header");
}
In your view (with custom icons):
@section Header
{
@Html.Partial("_CustomHeader")
}
A further solution is to derive all your models from a base model class that contains custom icon data, e.g.
public abstract class BaseModel
{
public List<Icon> Icons { get; set; }
}
public class ModelWithIcons : BaseModel
{
public ModelWithIcons()
{
// Set up icon data
}
}
The _header partial view is (still defined in the layout page) will use this base model and, with null checks, render any icons it finds:
@model BaseModel
<!-- Header HTML -->
@if (Model != null && Model.Icon)
{
// Render icons
}
<!-- More HTML -->
The obvious downside here is that all your models must derive from the BaseModel class or the partial view will throw an error.
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