Background and Motivation
Related to #28182.
There is a need for a feature that will allow customers to change a part of main layout depending on which page they are on. A solution to achieve that exists and was described in #28182 (comment). Similar solution was implemented as part of #10450. https://github.com/dotnet/aspnetcore/tree/main/src/Components/Components/src/Sections these classes are internal.
We want to make them a part of public API (and change a few things for other potential use cases).
Proposed API
SectionOutlet component that renders content provided by SectionContent with the same SectionId
public sealed class SectionOutlet : IComponent, IDisposable
{
[Parameter, EditorRequired] public object SectionId { get; set; }
}
public sealed class SectionContent : IComponent, IDisposable
{
[Parameter, EditorRequired] public object SectionId { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
{
Usage Examples
Common use case would be to use SectionOutlet component in MainLayout.razor and provide the desired content via SectionContent component in other pages.
This is not the only case. You could use SectionOutlet SectionContent to modify a part of parent component depending on which child components are rendered.
Example:
- Add this code into the default template's
MainLayout.razor:
@code{
internal static object TopbarSection = new();
}
- Add
SectionOutlet into the default template's MainLayout.razor:
<div class="top-row px-4">
<SectionOutlet SectionId="TopbarSection" />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
- Add
SectionContent into Counter.razor:
<SectionContent SectionId="MainLayout.TopbarSection">
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent>
You'll get this:

If you don't want to use a static field inMainlayout.razor you could also use a string as SectionId:
<SectionOutlet SectionId="@("topbar")" />
In Counter.razor:
<SectionContent SectionId="@("topbar")">
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent>
Alternative Designs
The original design with string Name as an identifier instead of object SectionId.
public sealed class SectionOutlet : IComponent, IDisposable
{
[Parameter, EditorRequired] public string Name { get; set; }
}
public sealed class SectionContent : IComponent, IDisposable
{
[Parameter, EditorRequired] public string Name { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
{
With this design you cannot hide your SectionOutlet. This is useful when you are developing a library and you don't want any accidental content in the user's app to be rendered in library's component.
Risks
Case when SectionId is IEquatable<T> and Equals(object), GetHashCode() not overriden.
Background and Motivation
Related to #28182.
There is a need for a feature that will allow customers to change a part of main layout depending on which page they are on. A solution to achieve that exists and was described in #28182 (comment). Similar solution was implemented as part of #10450. https://github.com/dotnet/aspnetcore/tree/main/src/Components/Components/src/Sections these classes are internal.
We want to make them a part of public API (and change a few things for other potential use cases).
Proposed API
SectionOutletcomponent that renders content provided bySectionContentwith the sameSectionIdUsage Examples
Common use case would be to use
SectionOutletcomponent inMainLayout.razorand provide the desired content viaSectionContentcomponent in other pages.This is not the only case. You could use
SectionOutletSectionContentto modify a part of parent component depending on which child components are rendered.Example:
MainLayout.razor:SectionOutletinto the default template'sMainLayout.razor:SectionContentintoCounter.razor:You'll get this:
If you don't want to use a static field in
Mainlayout.razoryou could also use a string asSectionId:In
Counter.razor:Alternative Designs
The original design with string
Nameas an identifier instead of objectSectionId.With this design you cannot hide your
SectionOutlet. This is useful when you are developing a library and you don't want any accidental content in the user's app to be rendered in library's component.Risks
Case when
SectionIdisIEquatable<T>andEquals(object),GetHashCode()not overriden.