RazorViewComponent 1.0.0
See the version list below for details.
dotnet add package RazorViewComponent --version 1.0.0
NuGet\Install-Package RazorViewComponent -Version 1.0.0
<PackageReference Include="RazorViewComponent" Version="1.0.0" />
paket add RazorViewComponent --version 1.0.0
#r "nuget: RazorViewComponent, 1.0.0"
// Install RazorViewComponent as a Cake Addin #addin nuget:?package=RazorViewComponent&version=1.0.0 // Install RazorViewComponent as a Cake Tool #tool nuget:?package=RazorViewComponent&version=1.0.0
<img src="Logo.png" alt="project icon" />
RazorViewComponent
What is it?
RazorViewComponent is a mashup of existing ASP.NET technologies that makes it very easy to create and use UI components in your Razor Pages projects.
<br>
Here is a sample of what it lets you do:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div>
<bs5-card
title="Sample Title"
subTitle="Sample Sub-Title"
cardCss="my-3">
<p>Some content for my sample card.</p>
<card-header>
<p>Some content for the card header</p>
</card-header>
<card-footer>
<p>Some content for the card footer</p>
</card-footer>
</bs5-card>
</div>
<br>
Okay, but how easy is it really?
Very easy, actually!
Add the nuget package to your project...
dotnet add package RazorViewComponent
Update View Imports...
// /Pages/_ViewImports.cshtml
@using WebApp1
@namespace WebApp1.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
// *** ADD THIS LINE ***
@addTagHelper *, WebApp1
Define the component...
// BootstrapCard.cshtml.cs
using Microsoft.AspNetCore.Razor.TagHelpers;
using RazorViewComponent;
namespace WebApp1.Pages.Shared.Components
{
[HtmlTargetElement("bs5-card")]
public class BootstrapCard : RazorViewComponent
{
[HtmlAttributeName("title")]
public string? CardTitle { get; set; }
[HtmlAttributeName("subTitle")]
public string? CardSubTitle { get; set; }
[HtmlAttributeName("cardCss")]
public string? CardCss { get; set; }
}
[HtmlTargetElement("card-header")]
public class BootstrapCardHeader : AutoNamedSlotComponent { }
[HtmlTargetElement("card-footer")]
public class BootstrapCardFooter : AutoNamedSlotComponent { }
// NOTE: Don't worry about 'magic' strings. I used them here only
// for the sake of brevity. Take a look at the sample project to
// see how to use constants to eliminate 'magic' strings.
}
And its view...
@model BootstrapCard;
<div class="card @Model.CardCss">
@if (Model.SlotHasContent("card-header"))
{
<div class="card-header">
@Model.RenderSlot("card-header")
</div>
}
<div class="card-body">
@if (Model.CardTitle is not null)
{
<h5 class="card-title">@Model.CardTitle</h5>
}
@if (Model.CardSubTitle is not null)
{
<h6 class="card-subtitle">@Model.CardSubTitle</h6>
}
@if (Model.HasChildContent())
{
<div class="mt-2">
@Model.RenderChildContent()
</div>
}
</div>
@if (Model.SlotHasContent("card-footer"))
{
<div class="card-footer">
@Model.RenderSlot("card-footer")
</div>
}
</div>
And, that's really all there is to it!
<br>
You have quite a bit of flexibility in what your components can do. You could, for instance, inject a service into your component to query a database based on the value of one of the components attributes (e.g. productId) in order to display product data in a consistent, component-based UI element. While that's not an especially practical example, it does illustrate the flexibility available to you. A more realistic approach would be to just provide a pre-populated Product object to your component.
<br>
Configuration
Location of view files
By default, RazorViewComponent
looks for views associated with a component in the /Shared/Components
subfolder under /Pages
(i.e. /Pages/Shared/Components/*.cshtml
). It uses the component's class name (without the 'Component' suffix, if present) as the view file name. So, as an example, for a component class named MyViewComponent
, the pathname for its associated view file would be /Pages/Shared/Components/MyView.cshtml
.
This path configuration applies only to component view (*.cshtml) files; the *.cs file containing the component's class declaration can be located anywhere in your project. It is only a convention to place the .cs and .cshtml files in the same location (e.g. MyView.cshtml.cs and MyView.cshtml).
The reason why component view files must be located under the /Pages
folder is that RazorViewComponent
uses the partial-view rendering capabilities built into ASP.NET to render component views.
Accordingly, view files must be located somewhere the ASP.NET Razor view engine can find them, which by default in a Razor Pages project is the /Pages
folder. The configuration for the Razor view engine in ASP.NET can be modified, of course, in the call to services.AddRazorPages()
.
IMPORTANT: If you change the location where ASP.NET searches for (partial) view files, you must also relocate the /Pages/Shared/Components/ folder to that new location (e.g. /NewPagesFolder/Shared/Components).
You can specify a different folder where RazorViewComponent
should look for component view files by configuring an instance of RazorViewComponentOptions
using a services.Configure<T>()
call.
For example, the following will change the folder where RazorViewComponent
looks for views to /Pages/MyComponents
.
services.Configure<RazorViewComponentOptions>(
options =>
{
options.ViewFilesLocation = "/MyComponents";
});
IMPORTANT: In all cases, the folder containing component view files must be a subfolder under the root folder (or the root folder itself) where ASP.NET will search for view files (i.e.
/Pages
, by default).
Limitations
RazorViewComponent
currently has the following limitations:
- Slots with no content will throw an exception. This is a pretty easy fix, but I'm not sure if it's something that should actually be allowed. I'm leaning toward yes, allow it!
<my-component> <my-slot> </my-slot> </my-component>
- Supports only one instance of a named slot in a component — you cannot declare the same slot more than once. This can certainly be addressed with a bit of work, but it's still under review/consideration as to whether it's useful in a practical sense.
<my-component> <my-slot>...</my-slot> <my-slot>...</my-slot> </my-component>
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- ThrowGuard (>= 1.0.3)
-
net7.0
- ThrowGuard (>= 1.0.3)
-
net8.0
- ThrowGuard (>= 1.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.