1

I am receiving the following error in ASP.NET MVC. "the following sections have been defined but have not been rendered for the layout page" - Now I know what the error is about, but can't figure a way around it in fact it probably should work but I don't know why it won't.

I have an index.cshtml page which renders all dynamically driven DB content. Pages can contain widgets (Reusable blocks on content). The index.cshtml code is below:

    @{
    Layout = AppSettings.LayoutFileDirectory + "/" + PageDAL.GetLayoutFileForPage(Model.Page);
    string currentSection = string.Empty;
}

    @if(!string.IsNullOrEmpty(Model.Page.PageTitle))
    {
           <h3>@Model.Page.PageTitle</h3>
    }


@Html.Raw(Model.Page.PageText)



@foreach (var item in Model.Page.WidgetsInPages)
{
    //if(IsSectionDefined(item.WidgetSection))
    //{

        string sectionName = item.WidgetSection;
        //don't want to redefine section
        if (currentSection!= sectionName)
        {
            DefineSection(sectionName, () =>
            {
                //render all this sections widgets
                foreach (var insider in Model.Page.WidgetsInPages.Where(w => w.WidgetSection == sectionName).OrderBy(w => w.WidgetSortOrder))
                {
                    if (insider.Widget.WidgetFile != null)
                    {
                        Write(Html.Partial(AppSettings.WidgetTemplatesDirectory + "/" + insider.Widget.WidgetFile, item.Widget));
                        //Write(Html.Partial(AppSettings.WidgetTemplatesDirectory + "/" + insider.Widget.WidgetFile, new {Widget=item.Widget}));
                    }

                }
            });
            currentSection = sectionName;
        }

    //}
}

Now I have a _DefaultTheme.cshtml with the following sections. (This is the primary layout page)

<div class="header">
      @RenderSection("_HeaderSection", false)
</div>



    <div class="container">
        @RenderSection("_AboveBodySection", false)
        @RenderBody()
        @RenderSection("_BelowBodySection", false)
    </div>

    @RenderSection("_AfterBodySection", false)

    <footer class="footer">
    <div class="container">
        @RenderSection("_FooterSection",false)
        @Html.Raw(FrontEnd.PopulateFooter(Model.Website))
    </div>

    </footer>

Adding widgets to the any page which has the _DefaultTheme layout works perfectly fine, but when I start inheriting pages it becomes an issue. I now have another page _DefaultThemeArticles.cshtml the master page is _DefaultTheme.cshtml

The _DefaultThemeArticles.cshtml contains this:

@{ 
    Layout = "~/Themes/_DefaultTheme.cshtml";
}


<div class="container">
    @RenderBody()
</div>

Now the error occurs when adding Widgets to any page which has this layout. I get this error:

The following sections have been defined but have not been rendered for the layout page "~/Themes/_DefaultThemeArticles.cshtml": "_BelowBodySection".

But the section _BelowBodySection has been defined in the master page, why would it not work here?.

  • 1
    It's not as automatic as you might think. You'll need to define the section in the child template if you're going to use it there and point it to the appropriate section on the parent template. See http://stackoverflow.com/questions/8578843/rendersection-in-nested-razor-templates. – Jasen Mar 09 '17 at 17:36

1 Answers1

0

The problem is that in your layout page, _DefaultTheme.cshtml, by writing all of these:

@RenderSection("_HeaderSection", false)
@RenderSection("_AboveBodySection", false)
@RenderSection("_BelowBodySection", false)
@RenderSection("_AfterBodySection", false)
@RenderSection("_FooterSection",false)

You are asserting that in any child page, like _DefaultThemeArticles, there must be a section defined for each of the above. If Razor doesn't find a particular section defined (in your case _BelowBodySection) in the child page, it throws the error. You can use the following Razor to solve this:

@if (IsSectionDefined("_BelowBodySection"))
{
    @RenderSection("_BelowBodySection")
}

This will only render the section if it exists.

Hope this helps.

coolboyjules
  • 2,300
  • 4
  • 22
  • 42
  • I understand that, but as seen in the index page I use the DefineSection method to write these out dynamically. Pages can have widgets, and those widgets contain a section name. The section name must exist and in this case they do exist in the parent layout. The DefineSection method should render those sections correct? –  Mar 09 '17 at 18:09