CshtmlComponent is a component framework, with an extensive feature set, for ASP.NET Core MVC and Razor Pages projects (not for Blazor). See the GitHub repository of CshtmlComponent here.
CshtmlComponent Named Slots
CshtmlComponent already supports the usage of named slots, but what about typed slots? This post will show how this can be achieved. This is not an extensive tutorial, so you should already be somewhat familiar with CshtmlComponent.
The Razor markup for a CshtmlComponent that supports named slots could look something like this:
@using SampleRazorPagesApplication
@model ExampleComponent
<div class="example-component">
<h1>
@Model.Title
</h1>
<div class="example-component-action-bar">
@Html.Raw(Model.NamedSlots["ActionBar"])
</div>
<div class="example-component-child-content">
@Html.Raw(Model.ChildContent)
</div>
</div>
Initialization of a CshtmlComponent with Named Slots
The component could then be initialized with:
<ExampleComponent Title="Hello World">
Some HTML that gets captured in Model.ChildContent.
<CshtmlSlot Name="ActionBar">
Some HTML that gets captured in Model.NamedSlots["ActionBar"].
</CshtmlSlot>
</ExampleComponent>
Note that the slot name must be explicitly stated. This works, but is somewhat annoying and error prone. Luckily, fixing this is quite easy with typed slots.
Typed Slot Definition
To define a typed slot one should create a class that inherits CshtmlComponentSlot
and set the Name
property in the constructor:
[HtmlTargetElement("ExampleComponentActionBar"]
public class ExampleComponentActionBar: CshtmlComponentSlot
{
public ExampleComponentActionBar(IHtmlHelper htmlHelper) : base(htmlHelper)
{
Name = "ActionBar";
}
}
That's it. You may wish to, for example, store the value for Name
as a static field for better maintainability, but this is not necessary.
Initialization of a CshtmlComponent with Typed Slots
With the typed slot definition, the example component can now be initialized like this:
<ExampleComponent Title="Hello World">
Some HTML that gets captured in Model.ChildContent.
<ExampleComponentActionBar>
Some HTML that gets captured in Model.NamedSlots["ActionBar"].
</ExampleComponentActionBar>
</ExampleComponent>
Note that the name no longer has to be explicitly specified.
Conclusions
CshtmlComponent supports both named and typed slots. Typed slots bring many advantages, such as making maintenance and refactoring significantly easier. This feature is not yet documented in the actual CshtmlComponent documentation, but will be in the future.
Please try out CshtmlComponent! You just might find it useful for MVC and Razor Pages projects!
Top comments (0)