RazorSlices 0.9.5
dotnet add package RazorSlices --version 0.9.5
NuGet\Install-Package RazorSlices -Version 0.9.5
<PackageReference Include="RazorSlices" Version="0.9.5" />
<PackageVersion Include="RazorSlices" Version="0.9.5" />
<PackageReference Include="RazorSlices" />
paket add RazorSlices --version 0.9.5
#r "nuget: RazorSlices, 0.9.5"
#:package RazorSlices@0.9.5
#addin nuget:?package=RazorSlices&version=0.9.5
#tool nuget:?package=RazorSlices&version=0.9.5
Razor Slices
Lightweight Razor-based templates for ASP.NET Core without MVC, Razor Pages, or Blazor, optimized for high-performance, unbuffered rendering with low allocations. Compatible with trimming and native AOT. Great for returning dynamically rendered HTML from Minimal APIs, middleware, etc. Supports .NET 8+
Getting Started
Install the NuGet package into your ASP.NET Core project (.NET 8+):
> dotnet add package RazorSlicesCreate a directory in your project called Slices and add a _ViewImports.cshtml file to it with the following content:
@inherits RazorSliceHttpResult @using System.Globalization; @using Microsoft.AspNetCore.Razor; @using Microsoft.AspNetCore.Http.HttpResults; @tagHelperPrefix __disable_tagHelpers__: @removeTagHelper *, Microsoft.AspNetCore.Mvc.RazorIn the same directory, add a Hello.cshtml file with the following content:
@inherits RazorSliceHttpResult<DateTime> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Hello from Razor Slices!</title> </head> <body> <p> Hello from Razor Slices! The time is @Model </p> </body> </html>Each .cshtml file will have a proxy type generated for it by the Razor Slices source generator that you can use as the generic argument to the various APIs in Razor Slices for rendering slices.
Add a minimal API to return the slice in your Program.cs:
app.MapGet("/hello", () => Results.Extensions.RazorSlice<MyApp.Slices.Hello, DateTime>(DateTime.Now));Optional: By default, all .cshtml files in your project are treated as Razor Slices (excluding _ViewImports.cshtml and ViewStart.cshtml). You can change this by setting the
EnableDefaultRazorSlicesproperty tofalseand theGenerateRazorSlicemetadata property of the desiredRazorGenerateitems totruein your project file, e.g.:<PropertyGroup> <EnableDefaultRazorSlices>false</EnableDefaultRazorSlices> </PropertyGroup> <ItemGroup> <RazorSlice Include="Slices\**\*.cshtml" Exclude="Slices\**\_Layout.cshtml;Slices\**\_ViewImports.cshtml" /> </ItemGroup>This will configure the Razor Slices source generator to only generate proxy types for .cshtml files in the Slices directory in your project.
Installation
NuGet Releases
This package is currently available from nuget.org:
> dotnet add package RazorSlices
CI Builds
If you wish to use builds from this repo's main branch you can install them from this repo's package feed.
Create a personal access token for your GitHub account with the
read:packagesscope with your desired expiration length:At the command line, navigate to your user profile directory and run the following command to add the package feed to your NuGet configuration, replacing the
<GITHUB_USER_NAME>and<PERSONAL_ACCESS_TOKEN>placeholders with the relevant values:~> dotnet nuget add source -n GitHub -u <GITHUB_USER_NAME> -p <PERSONAL_ACCESS_TOKEN> https://nuget.pkg.github.com/DamianEdwards/index.jsonYou should now be able to add a reference to the package specifying a version from the repository packages feed
See these instructions for further details about working with GitHub package feeds.
Features
The library is still new and features are being actively added.
Currently supported
ASP.NET Core 8.0 and above
Strongly-typed models (via
@inherits RazorSlice<MyModel>or@inherits RazorSliceHttpResult<MyModel>)Razor constructs:
Implicit expressions, e.g.
@someVariableExplicit expressions, e.g.
@(someBool ? thisThing : thatThing)Control structures, e.g.
@if(),@switch(), etc.Looping, e.g.
@for,@foreach,@while,@doCode blocks, e.g.
@{ var someThing = someOtherThing; }-
@functions { private readonly string _someString = "A very important string"; private int DoAThing() => 123; } Templated Razor methods, e.g.
@inherits RazorSlice<Todo> <h1>@Title(Model)</h1> @functions { private IHtmlContent Title(Todo todo) { <text>Todo @todo.Id: @todo.Title</text> return HtmlString.Empty; } }Templated Razor delegates, e.g.
@inherits RazorSlice<Todo> @{ var tmpl = @<div> This is a templated Razor delegate. The following value was passed in: @item </div>; } @tmpl(DateTime.Now)NOTE: Async templated Razor delegates are NOT supported and will throw an exception at runtime
DI-activated properties via
@injectRendering slices from slices (aka partials) via
@(await RenderPartialAsync<MyPartial>())Using slices as layouts for other slices, including layouts with strongly-typed models:
For the layout slice, inherit from
RazorLayoutSliceorRazorLayoutSlice<TModel>and use@await RenderBodyAsync()in the layout to render the body@inherits RazorLayoutSlice<LayoutModel> <!DOCTYPE html> <html lang="en"> <head> <title>@Model.Title</title> @await RenderSectionAsync("head") </head> <body> @await RenderBodyAsync() <footer> @await RenderSectionAsync("footer") </footer> </body> </html>For the slice using the layout, implement
IUsesLayout<TLayout>orIUsesLayout<TLayout, TModel>to declare which layout to use. If using a layout with a model, ensure you implement theLayoutModelproperty in your@functionsblock, e.g@inherits RazorSlice<SomeModel> @implements IUsesLayout<LayoutSlice, LayoutModel> <div> @* Content here *@ </div> @functions { public LayoutModel LayoutModel => new() { Title = "My Layout" }; }Layouts can render sections via
@await RenderSectionAsync("SectionName")and slices can render content into sections by overridingExecuteSectionAsync, e.g.:protected override Task ExecuteSectionAsync(string name) { if (name == "lorem-header") { <p class="text-info">This page renders a custom <code>IHtmlContent</code> type that contains lorem ipsum content.</p> } return Task.CompletedTask; }NOTE: The
@sectiondirective is not supported as it's incompatible with the rendering approach of Razor Slices
Asynchronous rendering, i.e. the template can contain
awaitstatements, e.g.@await WriteTheThing()Writing UTF8
byte[]values directly to the outputRendering directly to
PipeWriter,Stream,TextWriter,StringBuilder, andstringoutputs, including optimizations for not boxing struct values, zero-allocation rendering of primitives like numbers, etc. (rather than just callingToString()on everything)Return a slice instance directly as an
IResultin minimal APIs via@inherits RazorSliceHttpResultandResults.Extensions.RazorSlice("/Slices/Hello.cshtml")Full support for trimming and native AOT when used in conjunction with ASP.NET Core Minimal APIs
Generated Razor Slice proxy types are
public sealedby default. To unseal them and make thempublic partialfor your own customization, set theRazorSliceProxiesSealedproperty tofalsein your project file, e.g.:<PropertyGroup> <RazorSliceProxiesSealed>false</RazorSliceProxiesSealed> </PropertyGroup>
Interested in supporting but not sure yet
- Extensions to help support using HTMX with Razor Slices
- Getting small updates to the Razor compiler itself to get some usability and performance improvements, e.g.:
- Don't mark the template's
ExecuteAsyncmethod as anasyncmethod unless the template containsawaitstatements to save on the async state machine overhead - Support compiling static template elements to UTF8 string literals (
ReadOnlySpan<byte>) instead of string literals to save on the UTF16 to UTF8 conversion during rendering - Support disabling the default registered
@addtaghelperand@modeldirectives which rely on MVC
- Don't mark the template's
No intention to support
- Tag Helpers and View Components (they're tied to MVC and are intrinsically "heavy")
@modeldirective (the Razor compiler does not support its use in conjunction with custom base-types via@inherits)@attribute [Authorize](wrong layer of abstraction for minimal APIs, etc.)@sectiondirective (the Razor compiler emits code that is incompatible with the rendering approach of Razor Slices)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on RazorSlices:
| Package | Downloads |
|---|---|
|
BridgingIT.DevKit.Presentation.Web
bITdevKit: Empowering developers with modular components for modern application development, centered around Domain-Driven Design principles. Our goal is to empower developers by offering modular components that can be easily integrated into your projects. Whether you're working with repositories, commands, queries, or other components, the bITDevKit provides flexible solutions that can adapt to your specific needs. |
|
|
BridgingIT.DevKit.Presentation.Web.JobScheduling
bITdevKit: Empowering developers with modular components for modern application development, centered around Domain-Driven Design principles. Our goal is to empower developers by offering modular components that can be easily integrated into your projects. Whether you're working with repositories, commands, queries, or other components, the bITDevKit provides flexible solutions that can adapt to your specific needs. |
GitHub repositories (2)
Showing the top 2 popular GitHub repositories that depend on RazorSlices:
| Repository | Stars |
|---|---|
|
dodyg/practical-aspnetcore
Practical samples of ASP.NET Core 10 RC 2, 9, 8.0, 7.0, 6.0, 5.0, 3.1, 2.2, and 2.1,projects you can use. Readme contains explanations on all projects.
|
|
|
aspnet/Benchmarks
Benchmarks for ASP.NET Core
|
| Version | Downloads | Last Updated |
|---|---|---|
| 0.9.5 | 26,063 | 8/3/2025 |
| 0.9.4 | 15,759 | 7/30/2025 |
| 0.9.3 | 233 | 7/29/2025 |
| 0.9.2 | 11,915 | 6/25/2025 |
| 0.9.1 | 41,399 | 12/20/2024 |
| 0.9.0 | 8,014 | 12/19/2024 |
| 0.8.1 | 39,163 | 6/7/2024 |
| 0.8.0 | 210 | 6/7/2024 |
| 0.7.0 | 34,427 | 6/3/2023 |
| 0.6.2 | 295 | 5/31/2023 |
| 0.6.1 | 262 | 5/30/2023 |
| 0.6.0 | 263 | 5/30/2023 |
| 0.5.0 | 347 | 4/5/2023 |
| 0.4.0 | 384 | 3/24/2023 |
| 0.3.0 | 3,136 | 3/13/2023 |
| 0.2.0 | 356 | 3/10/2023 |
| 0.1.2 | 392 | 3/8/2023 |
| 0.1.1 | 346 | 3/8/2023 |
| 0.1.0 | 394 | 3/8/2023 |
| 0.1.0-pre.20230307.10 | 211 | 3/7/2023 |