Regira.Web 6.6.0

dotnet add package Regira.Web --version 6.6.0
                    
NuGet\Install-Package Regira.Web -Version 6.6.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Regira.Web" Version="6.6.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Regira.Web" Version="6.6.0" />
                    
Directory.Packages.props
<PackageReference Include="Regira.Web" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Regira.Web --version 6.6.0
                    
#r "nuget: Regira.Web, 6.6.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Regira.Web@6.6.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Regira.Web&version=6.6.0
                    
Install as a Cake Addin
#tool nuget:?package=Regira.Web&version=6.6.0
                    
Install as a Cake Tool

Regira Web

Regira Web provides Razor-based HTML template rendering plus common web utilities, middleware, and Swagger configuration.

Projects

Project Package Purpose
Common.Web Regira.Web Core web utilities, middleware, exception handling
Web.Analytics Regira.Web.Analytics Abstract visitor analytics — pluggable capture, enrichment, and storage hooks
Web.Analytics.GeoIP2 Regira.Web.Analytics.GeoIP2 Country/city enrichment from a local MaxMind GeoIP2/GeoLite2 database
Web.HTML.RazorComponents Regira.Web.HTML.RazorComponents Razor components (.razor) compiled with the app, rendered via ASP.NET Core's HtmlRenderer
Web.HTML.RazorEngineCore Regira.Web.HTML.RazorEngineCore Razor templates via RazorEngineCore
Web.HTML.RazorLight Regira.Web.HTML.RazorLight Razor templates via RazorLight
Web.Swagger Regira.Web.Swagger Swagger/OpenAPI JWT & API Key support

Host configuration (WebHostOptions), background task queues and the Windows Service installer live in Regira.System.Hosting — see System.

Installation


<PackageReference Include="Regira.Web" Version="6.*" />


<PackageReference Include="Regira.Web.Analytics" Version="6.*" />
<PackageReference Include="Regira.Web.Analytics.GeoIP2" Version="6.*" />


<PackageReference Include="Regira.Web.HTML.RazorEngineCore" Version="6.*" />
<PackageReference Include="Regira.Web.HTML.RazorLight" Version="6.*" />


<PackageReference Include="Regira.Web.HTML.RazorComponents" Version="6.*" />


<PackageReference Include="Regira.Web.Swagger" Version="6.*" />

HTML Template Parsing

IHtmlParser

Task<string> Parse<T>(string html, T model);

All three implementations share this interface.

HtmlTemplateParser (simple placeholder engine)

Replaces {key} tokens with the model's values. The model goes through the ISerializer first, so a key is the serialized name: Regira's JSON serializer camel-cases property names (Name → {name}, Customer.Name → {customer.name}) and keeps dictionary keys as written. A token with no value — a missing key, or a null the serializer leaves out — stays in the output as written.

A comment-marked block repeats its content once for each item of a collection, with that item's keys and a 1-based {rowNr}. Its name is letters only and starts lowercase. A block is not a condition: a true flag renders nothing. {key:format} formats a number inside a block; the optional valueConverter turns each top-level value into text (ToString() by default) and never sees block values.

<h1>{title}</h1>
<ul>

<li>{rowNr}. {title}: {price:0.00}</li>

</ul>

By default values are inserted as they are, so a value holding <b> comes out as markup. HtmlEncode = true encodes every text value, at the top level and in blocks; set it whenever the model carries user-supplied text. {key:raw} then writes a value unencoded.

ISerializer jsonSerializer = new JsonSerializer();
string template = "<p>Hello {name}!</p>";

var parser = new HtmlTemplateParser(jsonSerializer) { HtmlEncode = true };
string html = await parser.Parse(template, new { Name = "Alice" });

RazorEngineCore

Full Razor syntax. Strips @model directives and Layout blocks (not supported by the engine). Best for simple templates without layout inheritance.

By default it writes model values as they are, so a value holding <b> comes out as markup. HtmlEncode = true encodes every value a template writes with @, in text and in attribute values, the way RazorLight does; set it whenever the model carries user-supplied text. @Raw(value) then writes a value unencoded.

string razorTemplate = "<p>Hello @Model.Name</p>";
var model = new { Name = "Alice" };

IHtmlParser parser = new Regira.Web.HTML.RazorEngineCore.RazorTemplateParser(new()
{
    HtmlEncode = true
});
string html = await parser.Parse(razorTemplate, model);

RazorLight

Full Razor syntax, with the @model directive compiled as written. Encodes every value a template writes with @; @Raw(value) writes a value unencoded. The host project needs <PreserveCompilationContext>true</PreserveCompilationContext>: without it the first Parse throws RazorLightException (Can't load metadata reference from the entry assembly).

string razorTemplate = "<p>Hello @Model.Name</p>";
var model = new { Name = "Alice" };

IHtmlParser parser = new Regira.Web.HTML.RazorLight.RazorTemplateParser();
string html = await parser.Parse(razorTemplate, model);

Compiled Razor templates

Both Razor parsers compile a template into an assembly that stays loaded until the process exits, and cache it by the template text for the whole process: each distinct template compiles once, whichever parser instance renders it, and later calls only render. Keep the template text fixed and pass the data as the model. Data concatenated into the text makes a new template on every call, which compiles every time and grows memory without bound.

RazorLight's Options.TemplateKey is [Obsolete] and ignored: a parser renders the template it is given.

A runtime Razor template is code. RazorLight and RazorEngineCore compile it as C# and run it in your process, with its file system, network and configuration; there is no sandbox. Let only trusted administrators edit one, keep user text in the model (where @ encodes it), and for templates end users write use HtmlTemplateParser with HtmlEncode = true, which replaces tokens and runs nothing. Each edited or previewed version compiles a new assembly that stays loaded until the process exits. A template that does not compile throws the engine's own exception (RazorLight's TemplateCompilationException, RazorEngineCore's RazorEngineCompilationException), which lists each error with its line.


Razor Components

Regira.Web.HTML.RazorComponents renders a Razor component — a .razor file compiled with the application — to HTML with ASP.NET Core's HtmlRenderer. It takes a component type rather than template text, so RazorComponentRenderer implements IHtmlComponentRenderer rather than IHtmlParser. A template is checked at build time, nothing compiles at runtime, and the package has no third-party dependency. Templates that change without a rebuild — stored in a database or deployed as files — need RazorLight instead, edited by trusted administrators only (Compiled Razor templates); templates end users edit belong to HtmlTemplateParser.

IHtmlComponentRenderer

Task<string> Render(Type componentType, IDictionary<string, object?>? parameters = null);

// Extensions
Task<string> Render<TComponent>(IDictionary<string, object?>? parameters = null);
Task<string> Render<TComponent, TModel>(TModel model);   // sets the component's Model parameter

Each dictionary entry sets the component parameter of that name; the Type form serves a template picked at runtime.

Registration

using Regira.Web.HTML.Abstractions;
using Regira.Web.HTML.RazorComponents;

var services = new ServiceCollection();
services.AddTransient<IHtmlComponentRenderer, RazorComponentRenderer>();

Register it transient: the renderer takes the provider that resolves it, so @inject resolves from the request's scope. As a singleton it would hold the root provider, and a scoped service such as a DbContext fails. Without DI, new RazorComponentRenderer() renders any component that injects nothing.

A template

The model is a parameter named Model, which Render<TComponent, TModel> sets:

<h1>Invoice #@Model.Number</h1>
<p>Customer: @Model.CustomerName</p>

@code {
    [Parameter, EditorRequired] public InvoiceDto Model { get; set; } = null!;
}
string html = await renderer.Render<InvoiceTemplate, InvoiceDto>(invoice);

A .cshtml template ports by replacing @model InvoiceDto with the [Parameter] property and @Raw(value) with @((MarkupString)value).

The .razor files compile in the consuming project, which needs the Razor SDK: Microsoft.NET.Sdk.Web has it, and a worker, console app or class library uses Microsoft.NET.Sdk.Razor. A project on the Razor SDK that also holds .cshtml template files for RazorLight or RazorEngineCore sets <EnableDefaultRazorGenerateItems>false</EnableDefaultRazorGenerateItems>, so the SDK leaves them as template text rather than taking them for MVC views. PreserveCompilationContext is not needed for the components; RazorLight needs it.

Rendering behaviour

  • Encoding. Values are HTML-encoded; @((MarkupString)value) writes markup.
  • Async. OnInitializedAsync and OnParametersSetAsync are awaited before the HTML is returned.
  • Components. Child components and generic components (@typeparam) render.
  • Layouts. @layout has no effect. A shared document frame is a component with a ChildContent parameter that wraps the content.
  • HTML only. No NavigationManager, no event handlers, no render modes, no JavaScript interop.
  • Culture. The caller's CurrentCulture, so UseRequestLocalization() applies to the rendered HTML.
  • Whitespace. Whitespace between elements in code blocks is trimmed; @preservewhitespace true keeps it.
  • Exceptions pass through unwrapped: the template's own, and InvalidOperationException for a parameter the component does not declare or an @inject service the provider cannot resolve.
  • Memory. Each call renders on its own HtmlRenderer and disposes it, so nothing is retained between calls.

Common.Web Utilities

Exceptions and request culture

ASP.NET Core's own middleware covers both. AddProblemDetails() with UseExceptionHandler() logs an unhandled exception and answers a 500 problem response without its details; UseRequestLocalization() sets the request's culture from ?culture=, a cookie or Accept-Language, among the cultures the app supports.

var builder = WebApplication.CreateBuilder();
builder.Services.AddProblemDetails();

var app = builder.Build();
app.UseExceptionHandler();
app.UseRequestLocalization(options => options
    .SetDefaultCulture("en")
    .AddSupportedCultures("en", "nl-BE", "fr-BE")
    .AddSupportedUICultures("en", "nl-BE", "fr-BE"));
// Request: GET /api/products?culture=nl-BE  → sets nl-BE culture

RoutePrefixConvention

Apply a central route prefix to every controller. An absolute template (/x or ~/x, on a controller or an action) is not combined and skips the prefix: write the base into it.

var services = new ServiceCollection();
services.AddControllers(options =>
    options.UseCentralRoutePrefix(new RouteAttribute("api/v1")));

TextPlainInputFormatter

Enables [FromBody] string binding for text/plain requests.

var services = new ServiceCollection();
services.AddControllers(options =>
    options.InputFormatters.Insert(0, new TextPlainInputFormatter()));

ControllerExtensions, NamedFileResultExtensions and FormFileExtensions

// Return INamedFile as a download or inline
return this.File(namedFile, inline: true);
// The same from a minimal-API endpoint, as an IResult
return namedFile.ToFileResult(httpContext, inline: true);

// Read an upload as an INamedFile
var upload = formFile.ToNamedFile();
  • File() and ToFileResult() answer 404 for a file without content, and send X-Content-Type-Options: nosniff and, with every file but a PDF, Content-Security-Policy: sandbox, so a file served from the app's origin renders but runs no script, whatever its name or stored type. A PDF goes without: a sandbox keeps the browser's PDF viewer from loading. The sandbox is added to a policy the app already sent, not put in its place; a middleware that sets Content-Security-Policy once the response starts (OnStarting) must append to the header too, or it replaces the sandbox.
  • ToNamedFile() sets ContentType from the file name's extension (application/octet-stream when unknown), never from the type the client declared. Restrict uploads by extension where it matters.

RequestUtility

Extension methods on HttpRequest:

string  url     = Request.CurrentUrl();
Uri     baseUrl = Request.GetBaseUrl();
Uri     abs     = Request.GetAbsoluteUrl("/images/logo.png");
Uri?    referrer = Request.GetReferrer();
IPAddress? ip   = Request.GetIPAddress();

Web.Swagger

Add JWT Bearer and/or API Key inputs to the Swagger UI:

var builder = WebApplication.CreateBuilder();
builder.Services.AddSwaggerGen(o =>
{
    JwtAuthenticationExtensions.AddJwtAuthentication(o);
    // or
    ApiKeyAuthenticationExtensions.AddApiKeyAuthentication(o, parameterName: "X-Api-Key");
});

Make enums display as strings in Swagger:

var builder = WebApplication.CreateBuilder();
builder.Services.AddControllers().DisplayEnumAsString();

Overview

  1. Index — Overview, template engines, middleware, and Swagger
  2. Examples — HTML templating, exception handling, background tasks, Razor components

License

Apache License 2.0 — this package contains no license validation and no runtime limits. See LICENSE. A few companion packages are commercially licensed with a free tier; see the licensing overview.

Product 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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on Regira.Web:

Package Downloads
Regira.Entities.Web

REST/CRUD Web API for Regira entities: list, search, filter, sort and paging endpoints, as EntityControllerBase controllers or mapped minimal-API endpoints (MapEntityEndpoints). Top-level web entry point — brings the DependencyInjection and EF Core packages transitively. Free tier included — a license key removes the free-tier limits.

Regira.Security.Authentication.Web

ASP.NET Core authentication middleware and OpenAPI integration for Regira.

Regira.Web.HTML.RazorEngineCore

Razor-based HTML template rendering using RazorEngineCore for Regira.

Regira.Web.Swagger

Swagger/OpenAPI documentation extensions using Swashbuckle for Regira.

Regira.Web.HTML.RazorLight

Razor-based HTML template rendering using RazorLight for Regira.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
6.6.0 182 10/20/2026
6.5.0 278 10/4/2026
6.4.0 256 9/26/2026
6.3.3 231 9/22/2026
6.3.2 228 9/19/2026
6.3.1 219 9/17/2026
6.2.1 258 9/5/2026
6.1.3 238 8/26/2026
6.1.2 246 8/16/2026
6.1.1 225 8/12/2026
6.1.0 227 8/10/2026