HttpResponseTransformer 0.0.2.2-prerelease
See the version list below for details.
dotnet add package HttpResponseTransformer --version 0.0.2.2-prerelease
NuGet\Install-Package HttpResponseTransformer -Version 0.0.2.2-prerelease
<PackageReference Include="HttpResponseTransformer" Version="0.0.2.2-prerelease" />
<PackageVersion Include="HttpResponseTransformer" Version="0.0.2.2-prerelease" />
<PackageReference Include="HttpResponseTransformer" />
paket add HttpResponseTransformer --version 0.0.2.2-prerelease
#r "nuget: HttpResponseTransformer, 0.0.2.2-prerelease"
#:package HttpResponseTransformer@0.0.2.2-prerelease
#addin nuget:?package=HttpResponseTransformer&version=0.0.2.2-prerelease&prerelease
#tool nuget:?package=HttpResponseTransformer&version=0.0.2.2-prerelease&prerelease
HttpResponseTransformer
An ASP.NET Core library for injecting customizable transforms into the HTTP response pipeline. This library enables dynamic modification of HTTP responses, with specialized support for HTML document manipulation and content injection.
Motivation
This library was originally built with Jellyfin plugins in mind, as the standard plugin API doesn't provide UI customization capabilities. However, it is designed as a general-purpose tool for response transformation in any ASP.NET Core application and has no Jellyfin dependencies.
Installation
dotnet add package HttpResponseTransformer
Quick Start
Register the services and configure transforms in your Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseTransforms(builder => builder
.TransformDocument(config => config
.InjectScript(script => script
.FromUrl("https://cdn.example.com/script.js")
.At("//head")
.AsAsync())
.InjectStyleSheet(css => css
.FromUrl("https://cdn.example.com/styles.css")
.At("//head"))));
}
Response Pipeline
The library integrates with ASP.NET Core's middleware pipeline to intercept and transform HTTP responses. When ShouldTransform() returns true for any registered transform, the response stream is buffered in memory, transformed, and then sent to the client.
Important: When executing a transform, the entire response stream is buffered in memory. Care should be taken when working with large documents or streaming content.
ShouldTransform()orTransformDocument(x => x.When(...))should be used to target specific requests and avoid unnecessary buffering.
Transform Types
The library provides four types of transforms, each building on the previous level:
IResponseTransform- Base interface for all transforms, works with raw byte arraysTextResponseTransform- Base class for text-based responses, handles encoding/decoding automaticallyDocumentResponseTransform- Specialized for HTML documents, provides parsed DOM access via HtmlAgilityPackInjectContentResponseTransform- Pre-built transform for common content injection scenarios
Embedded Resource Pipeline
The library includes a built-in embedded resource serving system that works alongside the transform pipeline:
- Resource Registration: Embedded resources are automatically registered when using
FromEmbeddedResource() - Automatic Serving: The library serves embedded resources at generated URLs (e.g.,
/_/{namespace-hash}/{resource-hash}) - Content Types: Proper content-type headers are set based on file extensions
This allows bundling CSS, JavaScript, images, and other assets directly in an assembly and having them automatically served by the application.
Transform Execution Order
Transforms are executed in the order they are registered. Each transform receives the output of the previous transform, allowing multiple transformations to be chained together.
Usage Examples
The library provides several levels of response transformation:
HTML Document Injection
Use the built-in content injection system to add scripts, stylesheets, HTML content, and images to HTML documents using XPath targeting. This is the most common use case and requires no custom code.
services.AddResponseTransforms(builder => builder
.TransformDocument(config => config
.InjectScript(script => script.FromEmbeddedResource("MyApp.Scripts.analytics.js").At("//body"))
.InjectStyleSheet(css => css.FromUrl("/css/styles.css").At("//head"))
.InjectImage(img => img.FromUrl("/images/logo.png").At("//div[@id='header']"))
.InjectHtml(html => html.WithContent("<div>Welcome!</div>").At("//body"))));
Custom HTML Transforms
Implement DocumentResponseTransform to create custom HTML document manipulations with full access to the parsed HTML DOM via HtmlAgilityPack.
public class MetaTagTransform : DocumentResponseTransform
{
public override bool ShouldTransform(HttpContext context) =>
context.Request.Path.StartsWithSegments("/static/html");
public override void ExecuteTransform(HttpContext context, ref HtmlDocument document)
{
var head = document.DocumentNode.SelectSingleNode("//head");
var metaTag = document.CreateElement("meta");
metaTag.SetAttributeValue("name", "generated-at");
metaTag.SetAttributeValue("content", DateTime.UtcNow.ToString());
head?.AppendChild(metaTag);
}
}
Custom Text Transforms
Implement TextResponseTransform to perform string-based transformations on any text-based HTTP responses (HTML, JSON, XML, etc.).
public class TokenReplacementTransform : TextResponseTransform
{
public override bool ShouldTransform(HttpContext context) =>
context.Response.ContentType?.Contains("text/html") == true;
public override void ExecuteTransform(HttpContext context, ref string content)
{
content = content.Replace("{{USER_NAME}}", context.User.Identity?.Name ?? "Guest");
}
}
Custom Binary Transforms
Implement IResponseTransform directly to work with raw byte arrays for complete control over any response type.
public class ResizeImageTransform : IResponseTransform
{
public bool ShouldTransform(HttpContext context) =>
context.Response.ContentType?.StartsWith("image/") == true;
public void ExecuteTransform(HttpContext context, ref byte[] content)
{
// Resize image logic here
content = ResizeImage(content, maxWidth: 800, maxHeight: 600);
}
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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 was computed. 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- HtmlAgilityPack (>= 1.12.3)
- Microsoft.AspNetCore.Http.Abstractions (>= 2.3.0)
- Microsoft.AspNetCore.Mvc.Core (>= 2.3.0)
- System.Collections.Immutable (>= 9.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1.13 | 221 | 10/14/2025 |
| 1.0.0.12-prerelease | 204 | 10/14/2025 |
| 0.1.2.11-prerelease | 229 | 10/4/2025 |
| 0.1.0.9-prerelease | 203 | 10/2/2025 |
| 0.0.8.8-prerelease | 200 | 10/2/2025 |
| 0.0.7.7-prerelease | 201 | 9/29/2025 |
| 0.0.6.6-prerelease | 196 | 9/29/2025 |
| 0.0.5.5-prerelease | 136 | 9/27/2025 |
| 0.0.4.4-prerelease | 128 | 9/27/2025 |
| 0.0.4.3-prerelease | 136 | 9/27/2025 |
| 0.0.2.2-prerelease | 142 | 9/27/2025 |