Codebelt
v10.5.5

Cuemon.AspNetCore.Razor.TagHelpers

Compose asset URLs for app and CDN resources with reusable Razor tag helpers and optional versioned cache busting.

.NET 10.0 / .NET 9.0 MIT 57,619 downloads

Overview

Cuemon.AspNetCore.Razor.TagHelpers turns base-URL configuration and optional cache-busting into rendered <img>, <link>, and <script> tags for assets that live on an application-controlled host or a CDN. Instead of repeating host names, schemes, and version query-string logic in Razor markup, you configure AppTagHelperOptions or CdnTagHelperOptions and use the matching app-* or cdn-* tag helper.

The package builds on Cuemon.AspNetCore for the ICacheBusting abstraction and keeps its scope on tag rendering and URL composition. It also exposes abstract base classes for image, link, and script helpers so you can create custom tag helpers that follow the same formatting and versioning rules.

Key APIs

AppImageTagHelper targets <app-img> and renders a normal <img> element whose src value is prefixed with the formatted AppTagHelperOptions.BaseUrl. It also carries through optional id, class, alt, and title attributes and appends ?v={version} when an ICacheBusting implementation is supplied.

AppLinkTagHelper targets <app-link> and renders <link> markup for application-hosted assets. It inherits the default rel="stylesheet" and type="text/css" behavior from LinkTagHelper<TOptions>, while still letting callers override Rel, Type, and Href.

AppScriptTagHelper targets <app-script> and renders <script> elements for application-hosted scripts. Its base implementation writes type="text/javascript", composes the final src from the configured base URL, and emits defer="defer" when Defer is set.

CdnImageTagHelper, CdnLinkTagHelper, and CdnScriptTagHelper mirror the app-hosted helpers for CDN-hosted assets. They bind to CdnTagHelperOptions, so the same tag-building logic can point at a different host and scheme without changing Razor markup shape.

TagHelperOptions is the package's central configuration model. BaseUrl, Scheme, and GetFormattedBaseUrl() determine whether generated URLs are plain paths, protocol-relative URLs, or fully qualified http or https addresses.

CacheBustingTagHelper<TOptions> is the reusable base for custom helpers. It exposes the configured Options, the protected CacheBusting dependency, and UseCacheBusting, which the specialized image, link, and script helpers use when composing versioned asset URLs.

Basic usage

using System.Collections.Generic;
using System.Threading.Tasks;
using Codebelt.Extensions.Xunit;
using Cuemon.Net;
using Cuemon.AspNetCore.Configuration;
using Cuemon.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Options;
using Xunit;

namespace MyProject.Tests;

public sealed class AppImageTagHelperTest : Test
{
    public AppImageTagHelperTest(ITestOutputHelper output) : base(output) { }

    [Fact]
    public async Task ShouldComposeRelativeImageUrl_WithCacheBusting()
    {
        var sut = new AppImageTagHelper(
            Options.Create(new AppTagHelperOptions { Scheme = ProtocolUriScheme.Relative, BaseUrl = "static.cuemon.net" }),
            new FixedCacheBusting("20260529"));
        sut.Class = "hero-logo-image";
        sut.Src = "cuemon-logo.svg";
        sut.Alt = "Cuemon for .NET";

        var context = new TagHelperContext(new TagHelperAttributeList(), new Dictionary<object, object>(), "img");
        var output = new TagHelperOutput("app-img", new TagHelperAttributeList(), (_, _) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent()));

        await sut.ProcessAsync(context, output);

        var src = output.Attributes["src"].Value?.ToString();
        Assert.Equal("img", output.TagName);
        Assert.Equal("//static.cuemon.net/cuemon-logo.svg?v=20260529", src);
        TestOutput.WriteLine($"{output.TagName}: {src}");
    }

    private sealed class FixedCacheBusting : ICacheBusting
    {
        public FixedCacheBusting(string version) => Version = version;
        public string Version { get; }
    }
}

Use this pattern when your Razor page needs asset tags that always point at an application-owned static host and should participate in versioned cache busting. It matters because the tag helper keeps host formatting and version-query logic in one configured component instead of scattering string concatenation across markup.

Installation

dotnet add package Cuemon.AspNetCore.Razor.TagHelpers

Usage guidance

Use Cuemon.AspNetCore.Razor.TagHelpers when your Razor views need repeatable URL composition for app or CDN assets and you want cache-busting support to ride along with the rendered tag. If plain framework tags and normal static-file paths already describe your asset layout, stay with standard Razor markup and only move up to these helpers when the host, scheme, or versioning rules need to be centralized.

Family packages