diff --git a/.docfx/api/types/Cuemon.AspNetCore.Razor.TagHelpers.TagHelperBaseUrlMode.md b/.docfx/api/types/Cuemon.AspNetCore.Razor.TagHelpers.TagHelperBaseUrlMode.md new file mode 100644 index 00000000..856affa9 --- /dev/null +++ b/.docfx/api/types/Cuemon.AspNetCore.Razor.TagHelpers.TagHelperBaseUrlMode.md @@ -0,0 +1,41 @@ +--- +uid: Cuemon.AspNetCore.Razor.TagHelpers.TagHelperBaseUrlMode +example: +- *content +--- + +The `TagHelperBaseUrlMode` enumeration controls how the base URL of a static resource is resolved by the app- and CDN-scoped tag helpers. `Configured` (the default) resolves the base URL exclusively from the configured `BaseUrl` and `Scheme`, whereas `Automatic` uses the configured `BaseUrl` when present and otherwise derives the base URL from the current HTTP request — useful when the same deployment is served from multiple origins. The following example demonstrates both modes through `CdnTagHelperOptions` and `GetFormattedBaseUrl`. + +```csharp +using System; +using Cuemon.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Http; + +namespace DocfxExamples; + +public class TagHelperBaseUrlModeExample +{ + public void Demonstrate() + { + var configured = new CdnTagHelperOptions + { + BaseUrlMode = TagHelperBaseUrlMode.Configured, + Scheme = ProtocolUriScheme.Https, + BaseUrl = "static.example.com" + }; + Console.WriteLine(configured.GetFormattedBaseUrl()); // Output: https://static.example.com/ + + var automatic = new CdnTagHelperOptions + { + BaseUrlMode = TagHelperBaseUrlMode.Automatic, + BaseUrl = null // No fixed origin, so fall back to the current HTTP request. + }; + var request = new DefaultHttpContext().Request; + request.Scheme = "https"; + request.Host = new HostString("app.example.com"); + request.PathBase = "/myapp"; + Console.WriteLine(automatic.GetFormattedBaseUrl(request)); // Output: https://app.example.com/myapp/ + } +} + +``` diff --git a/.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt index 4a4a3643..5b34bab1 100644 --- a/.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore.App/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt index 3e4f2e64..785ed3db 100644 --- a/.nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore.Authentication/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt index 2dbd9e08..5b88a382 100644 --- a/.nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore.Mvc/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt index 4a4a3643..0411eed4 100644 --- a/.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore.Razor.TagHelpers/PackageReleaseNotes.txt @@ -1,3 +1,15 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + +# New Features +- ADDED `TagHelperBaseUrlMode` enum to control how base URLs are resolved in tag helper options +- ADDED automatic base URL resolution to `CacheBustingTagHelper` via the new `ResolveUrl` method +- ADDED `ViewContext` property to `CacheBustingTagHelper` to enable access to the current HTTP request context +- EXTENDED `ImageTagHelper`, `LinkTagHelper`, and `ScriptTagHelper` to support automatic URL resolution from the current HTTP request when `TagHelperBaseUrlMode.Automatic` is configured + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt b/.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt index 176d9d7b..ddf0d244 100644 --- a/.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.AspNetCore/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Core.App/PackageReleaseNotes.txt b/.nuget/Cuemon.Core.App/PackageReleaseNotes.txt index afe9d5bc..3ffb84e3 100644 --- a/.nuget/Cuemon.Core.App/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Core.App/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Core/PackageReleaseNotes.txt b/.nuget/Cuemon.Core/PackageReleaseNotes.txt index cc9b04f7..5e30221d 100644 --- a/.nuget/Cuemon.Core/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Core/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt b/.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Data.Integrity/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt b/.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt index 9bf3caa9..247ba502 100644 --- a/.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Data.SqlClient/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Data/PackageReleaseNotes.txt b/.nuget/Cuemon.Data/PackageReleaseNotes.txt index c75594dc..446fb3f7 100644 --- a/.nuget/Cuemon.Data/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Data/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt b/.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Diagnostics/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt index 4a4a3643..5b34bab1 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Authentication/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt index 150f28cb..8e7cafd0 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt index a542383f..bb94ff80 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt index 4a4a3643..5b34bab1 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Mvc.RazorPages/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt index 1ef27e96..e82ace68 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Mvc/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt index 32422597..2cef943a 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Text.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt index 8505d139..60b98e80 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt index bceeb887..ff8d3226 100644 --- a/.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.AspNetCore/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10 and .NET 9 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10 and .NET 9 diff --git a/.nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt index b0ae981f..5248eed6 100644 --- a/.nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Collections.Generic/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Collections.Specialized/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt index be34c48f..4bd8eabe 100644 --- a/.nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Core/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Data.Integrity/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Data/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt index b7ee357d..630702d2 100644 --- a/.nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.DependencyInjection/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt index 61f74d3d..a0a76b3c 100644 --- a/.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Diagnostics/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.FileProviders.Physical/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.FileProviders.Physical/PackageReleaseNotes.txt index 867efaa6..c0f5eb25 100644 --- a/.nuget/Cuemon.Extensions.FileProviders.Physical/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.FileProviders.Physical/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt index 2f731533..4ff36bd8 100644 --- a/.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Hosting/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt index fe752f27..a56b5162 100644 --- a/.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.IO/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9, .NET Standard 2.1 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Net/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Reflection/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Runtime.Caching/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt index e1fc44ff..ebc24d2d 100644 --- a/.nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Text.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Text/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt index 884ecb61..61cb1032 100644 --- a/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Threading/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt b/.nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt index 0573e6e8..0c301807 100644 --- a/.nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Extensions.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.IO/PackageReleaseNotes.txt b/.nuget/Cuemon.IO/PackageReleaseNotes.txt index 5a0ca50d..32b0a91b 100644 --- a/.nuget/Cuemon.IO/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.IO/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Kernel/PackageReleaseNotes.txt b/.nuget/Cuemon.Kernel/PackageReleaseNotes.txt index 60d73364..46235380 100644 --- a/.nuget/Cuemon.Kernel/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Kernel/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Net/PackageReleaseNotes.txt b/.nuget/Cuemon.Net/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Net/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Net/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Resilience/PackageReleaseNotes.txt b/.nuget/Cuemon.Resilience/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Resilience/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Resilience/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt b/.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt index 64c75fbf..199041f7 100644 --- a/.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Runtime.Caching/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt b/.nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt index 15507648..651301fb 100644 --- a/.nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Security.Cryptography/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Threading/PackageReleaseNotes.txt b/.nuget/Cuemon.Threading/PackageReleaseNotes.txt index b1121191..381d8f14 100644 --- a/.nuget/Cuemon.Threading/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Threading/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/.nuget/Cuemon.Xml/PackageReleaseNotes.txt b/.nuget/Cuemon.Xml/PackageReleaseNotes.txt index 521d8a0a..a5678008 100644 --- a/.nuget/Cuemon.Xml/PackageReleaseNotes.txt +++ b/.nuget/Cuemon.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.7.0 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.6.0 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 096c2f40..466dff02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), For more details, please refer to `PackageReleaseNotes.txt` on a per assembly basis in the `.nuget` folder. +## [10.7.0] - 2026-08-12 + +This is a minor release focused on enhancing Razor tag helper flexibility with automatic base URL resolution and modernizing package dependency management. The release introduces opt-in automatic base URL derivation from the current HTTP request while maintaining backward compatibility with the default configured mode. Tag helper functionality remains stable while new capabilities provide greater flexibility for dynamic deployment scenarios. + +### Added + +- `TagHelperBaseUrlMode` enumeration with `Configured` and `Automatic` modes to control base URL resolution strategy, +- Automatic base URL resolution capability in tag helpers allowing dynamic derivation from the current HTTP request scheme, host, and path base when `BaseUrlMode` is set to `Automatic`, +- `ViewContext` property injection in `CacheBustingTagHelper` base class to enable HTTP request context access for automatic URL resolution, +- `ResolveUrl` protected method in tag helper base class for consistent URL path normalization and base URL composition, +- Comprehensive test coverage for automatic base URL resolution across `AppImageTagHelper`, `AppLinkTagHelper`, and `AppScriptTagHelper` with test factory helper. + +### Changed + +- Central package transitive pinning enabled in `Directory.Packages.props` for improved transitive dependency resolution, requiring explicit declaration of transitive dependencies in affected projects, +- Package dependencies updated to latest compatible versions across all supported target frameworks: Microsoft.Data.Sqlite (10.0.10 → 10.0.11, 9.0.18 → 9.0.19), Microsoft.Extensions packages (10.0.10 → 10.0.11, 9.0.18 → 9.0.19), System.Text.Json (10.0.10 → 10.0.11), +- Newtonsoft.Json added as a conditional dependency for Cuemon.Core.Tests to explicitly manage transitive package resolution with transitive pinning enabled. + ## [10.6.0] - 2026-08-07 This is a minor release that combines new portable file provider and async retry capabilities with bug fixes for retry, timeout, cancellation, and exception-handling edge cases. Existing public APIs remain available, while the corrected failure and retry behavior may differ for affected edge cases. The release also includes comprehensive dependency updates across all supported target frameworks. @@ -1856,6 +1874,7 @@ This release was primarily focused on adapting a more modern way of performing C - XmlWriterUtility class from Cuemon.Xml namespace - XmlWriterUtilityExtensions class from the Cuemon.Xml namespace +[10.7.0]: https://github.com/codebeltnet/cuemon/compare/v10.6.0...v10.7.0 [10.6.0]: https://github.com/codebeltnet/cuemon/compare/v10.5.5...v10.6.0 [10.5.5]: https://github.com/codebeltnet/cuemon/compare/v10.5.4...v10.5.5 [10.5.4]: https://github.com/codebeltnet/cuemon/compare/v10.5.3...v10.5.4 diff --git a/Directory.Packages.props b/Directory.Packages.props index 490f661a..92f77317 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,6 +1,7 @@ true + true @@ -14,6 +15,7 @@ + @@ -22,33 +24,33 @@ - + - - - - - + + + + + - + - - - - - - + + + + + + - - - - - - + + + + + + diff --git a/src/Cuemon.AspNetCore.Razor.TagHelpers/AppTagHelperOptions.cs b/src/Cuemon.AspNetCore.Razor.TagHelpers/AppTagHelperOptions.cs index 022c4987..4131c1f4 100644 --- a/src/Cuemon.AspNetCore.Razor.TagHelpers/AppTagHelperOptions.cs +++ b/src/Cuemon.AspNetCore.Razor.TagHelpers/AppTagHelperOptions.cs @@ -19,6 +19,10 @@ public class AppTagHelperOptions : TagHelperOptions /// /// /// + /// + /// + /// + /// /// /// null /// diff --git a/src/Cuemon.AspNetCore.Razor.TagHelpers/CacheBustingTagHelper.cs b/src/Cuemon.AspNetCore.Razor.TagHelpers/CacheBustingTagHelper.cs index 946d5527..d7d42a66 100644 --- a/src/Cuemon.AspNetCore.Razor.TagHelpers/CacheBustingTagHelper.cs +++ b/src/Cuemon.AspNetCore.Razor.TagHelpers/CacheBustingTagHelper.cs @@ -1,6 +1,10 @@ -using Cuemon.AspNetCore.Configuration; +using System; +using System.Globalization; +using Cuemon.AspNetCore.Configuration; using Cuemon.Configuration; using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.Extensions.Options; namespace Cuemon.AspNetCore.Razor.TagHelpers; @@ -34,9 +38,36 @@ protected CacheBustingTagHelper(IOptions setup, ICacheBusting cacheBus /// true if an object implementing the interface is specified; otherwise, false. protected bool UseCacheBusting => CacheBusting != null; + /// + /// Gets or sets the current view context. + /// + /// The current view context. + [HtmlAttributeNotBound] + [ViewContext] + public ViewContext ViewContext { get; set; } + /// /// Gets the configured options of this instance. /// /// The configured options of this instance. public TOptions Options { get; } + + /// + /// Resolves the fully qualified URL of the specified static resource. + /// + /// The relative path of the static resource. + /// The fully qualified URL of the specified static resource. + protected string ResolveUrl(string path) + { + var baseUrl = Options.GetFormattedBaseUrl(ViewContext?.HttpContext?.Request); + var resolvedPath = NormalizePath(path, !string.IsNullOrWhiteSpace(baseUrl)); + return string.Concat(baseUrl, UseCacheBusting ? string.Create(CultureInfo.InvariantCulture, $"{resolvedPath}?v={CacheBusting.Version}") : resolvedPath); + } + + private static string NormalizePath(string path, bool normalize) + { + if (!normalize || string.IsNullOrWhiteSpace(path)) { return path; } + if (path.StartsWith("~/", StringComparison.Ordinal)) { path = path.Substring(2); } + return path.TrimStart('/'); + } } diff --git a/src/Cuemon.AspNetCore.Razor.TagHelpers/CdnTagHelperOptions.cs b/src/Cuemon.AspNetCore.Razor.TagHelpers/CdnTagHelperOptions.cs index ca8aaa8d..e737b590 100644 --- a/src/Cuemon.AspNetCore.Razor.TagHelpers/CdnTagHelperOptions.cs +++ b/src/Cuemon.AspNetCore.Razor.TagHelpers/CdnTagHelperOptions.cs @@ -19,6 +19,10 @@ public class CdnTagHelperOptions : TagHelperOptions /// /// /// + /// + /// + /// + /// /// /// null /// diff --git a/src/Cuemon.AspNetCore.Razor.TagHelpers/ImageTagHelper.cs b/src/Cuemon.AspNetCore.Razor.TagHelpers/ImageTagHelper.cs index 54847a27..8732c980 100644 --- a/src/Cuemon.AspNetCore.Razor.TagHelpers/ImageTagHelper.cs +++ b/src/Cuemon.AspNetCore.Razor.TagHelpers/ImageTagHelper.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using System.Threading.Tasks; +using System.Threading.Tasks; using Cuemon.AspNetCore.Configuration; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.Options; @@ -62,7 +61,7 @@ public override Task ProcessAsync(TagHelperContext context, TagHelperOutput outp output.TagName = "img"; if (!string.IsNullOrWhiteSpace(Id)) { output.Attributes.Add("id", Id); } if (!string.IsNullOrWhiteSpace(Class)) { output.Attributes.Add("class", Class); } - output.Attributes.Add("src", string.Concat(Options.GetFormattedBaseUrl(), UseCacheBusting ? string.Create(CultureInfo.InvariantCulture, $"{Src}?v={CacheBusting.Version}") : Src)); + output.Attributes.Add("src", ResolveUrl(Src)); if (!string.IsNullOrWhiteSpace(Alt)) { output.Attributes.Add("alt", Alt); } if (!string.IsNullOrWhiteSpace(Title)) { output.Attributes.Add("title", Title); } return Task.CompletedTask; diff --git a/src/Cuemon.AspNetCore.Razor.TagHelpers/LinkTagHelper.cs b/src/Cuemon.AspNetCore.Razor.TagHelpers/LinkTagHelper.cs index 6afff710..9c85b21c 100644 --- a/src/Cuemon.AspNetCore.Razor.TagHelpers/LinkTagHelper.cs +++ b/src/Cuemon.AspNetCore.Razor.TagHelpers/LinkTagHelper.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using System.Threading.Tasks; +using System.Threading.Tasks; using Cuemon.AspNetCore.Configuration; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Razor.TagHelpers; @@ -52,7 +51,7 @@ public override Task ProcessAsync(TagHelperContext context, TagHelperOutput outp output.TagMode = TagMode.StartTagOnly; output.TagName = "link"; output.Attributes.Add("rel", Rel); - output.Attributes.Add("href", string.Concat(Options.GetFormattedBaseUrl(), UseCacheBusting ? string.Create(CultureInfo.InvariantCulture, $"{Href}?v={CacheBusting.Version}") : Href)); + output.Attributes.Add("href", ResolveUrl(Href)); if (!string.IsNullOrWhiteSpace(Type)) { output.Attributes.Add("type", new HtmlString(Type)); } return Task.CompletedTask; } diff --git a/src/Cuemon.AspNetCore.Razor.TagHelpers/ScriptTagHelper.cs b/src/Cuemon.AspNetCore.Razor.TagHelpers/ScriptTagHelper.cs index 3308bbd8..8ed03af9 100644 --- a/src/Cuemon.AspNetCore.Razor.TagHelpers/ScriptTagHelper.cs +++ b/src/Cuemon.AspNetCore.Razor.TagHelpers/ScriptTagHelper.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using System.Threading.Tasks; +using System.Threading.Tasks; using Cuemon.AspNetCore.Configuration; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.Options; @@ -43,7 +42,7 @@ public override Task ProcessAsync(TagHelperContext context, TagHelperOutput outp output.TagMode = TagMode.StartTagAndEndTag; output.TagName = "script"; output.Attributes.Add("type", "text/javascript"); - output.Attributes.Add("src", string.Concat(Options.GetFormattedBaseUrl(), UseCacheBusting ? string.Create(CultureInfo.InvariantCulture, $"{Src}?v={CacheBusting.Version}") : Src)); + output.Attributes.Add("src", ResolveUrl(Src)); if (Defer) { output.Attributes.Add("defer", "defer"); } return Task.CompletedTask; } diff --git a/src/Cuemon.AspNetCore.Razor.TagHelpers/TagHelperBaseUrlMode.cs b/src/Cuemon.AspNetCore.Razor.TagHelpers/TagHelperBaseUrlMode.cs new file mode 100644 index 00000000..55c777ca --- /dev/null +++ b/src/Cuemon.AspNetCore.Razor.TagHelpers/TagHelperBaseUrlMode.cs @@ -0,0 +1,15 @@ +namespace Cuemon.AspNetCore.Razor.TagHelpers; +/// +/// Specifies how the base URL of a static resource is resolved. +/// +public enum TagHelperBaseUrlMode +{ + /// + /// Specifies that the base URL is resolved exclusively from the configured values of and . + /// + Configured, + /// + /// Specifies that the base URL is resolved from the configured value of when available; otherwise from the current HTTP request. + /// + Automatic +} diff --git a/src/Cuemon.AspNetCore.Razor.TagHelpers/TagHelperOptions.cs b/src/Cuemon.AspNetCore.Razor.TagHelpers/TagHelperOptions.cs index 37fbe684..e7e1364d 100644 --- a/src/Cuemon.AspNetCore.Razor.TagHelpers/TagHelperOptions.cs +++ b/src/Cuemon.AspNetCore.Razor.TagHelpers/TagHelperOptions.cs @@ -1,6 +1,7 @@ using System.Globalization; using Cuemon.Configuration; using Cuemon.Text; +using Microsoft.AspNetCore.Http; namespace Cuemon.AspNetCore.Razor.TagHelpers; /// @@ -9,10 +10,10 @@ namespace Cuemon.AspNetCore.Razor.TagHelpers; public abstract class TagHelperOptions : IParameterObject { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// - /// The following table shows the initial property values for an instance of . + /// The following table shows the initial property values for an instance of . /// /// /// Property @@ -23,6 +24,10 @@ public abstract class TagHelperOptions : IParameterObject /// /// /// + /// + /// + /// + /// /// /// null /// @@ -30,6 +35,7 @@ public abstract class TagHelperOptions : IParameterObject /// protected TagHelperOptions() { + BaseUrlMode = TagHelperBaseUrlMode.Configured; Scheme = ProtocolUriScheme.Relative; } @@ -39,6 +45,12 @@ protected TagHelperOptions() /// The of these options. public ProtocolUriScheme Scheme { get; set; } + /// + /// Gets or sets the base URL resolution mode of these options. + /// + /// The base URL resolution mode of these options. + public TagHelperBaseUrlMode BaseUrlMode { get; set; } + /// /// Gets or sets the base URL of these options. /// @@ -51,20 +63,34 @@ protected TagHelperOptions() /// The base URL of this instance, formatted according to the defined . public string GetFormattedBaseUrl() { - var baseUrlIsNullOrEmpty = string.IsNullOrWhiteSpace(BaseUrl); + if (string.IsNullOrWhiteSpace(BaseUrl)) { return ""; } var baseUrlWithForwardingSlash = new Stem(BaseUrl).AttachSuffix("/"); switch (Scheme) { case ProtocolUriScheme.None: - return baseUrlIsNullOrEmpty ? "" : string.Create(CultureInfo.InvariantCulture, $"{baseUrlWithForwardingSlash}"); + return string.Create(CultureInfo.InvariantCulture, $"{baseUrlWithForwardingSlash}"); case ProtocolUriScheme.Http: - return baseUrlIsNullOrEmpty ? "" : string.Create(CultureInfo.InvariantCulture, $"{nameof(UriScheme.Http).ToLowerInvariant()}://{baseUrlWithForwardingSlash}"); + return string.Create(CultureInfo.InvariantCulture, $"{nameof(UriScheme.Http).ToLowerInvariant()}://{baseUrlWithForwardingSlash}"); case ProtocolUriScheme.Https: - return baseUrlIsNullOrEmpty ? "" : string.Create(CultureInfo.InvariantCulture, $"{nameof(UriScheme.Https).ToLowerInvariant()}://{baseUrlWithForwardingSlash}"); + return string.Create(CultureInfo.InvariantCulture, $"{nameof(UriScheme.Https).ToLowerInvariant()}://{baseUrlWithForwardingSlash}"); case ProtocolUriScheme.Relative: - return baseUrlIsNullOrEmpty ? "" : string.Create(CultureInfo.InvariantCulture, $"//{baseUrlWithForwardingSlash}"); + return string.Create(CultureInfo.InvariantCulture, $"//{baseUrlWithForwardingSlash}"); default: return ""; } } + + /// + /// Gets the base URL of this instance, resolved from the configured values of this instance or the specified . + /// + /// The current HTTP request that may provide the effective scheme, host and application base path when is and is not configured. + /// The base URL of this instance, resolved from the configured values of this instance or the specified . + public string GetFormattedBaseUrl(HttpRequest request) + { + if (BaseUrlMode == TagHelperBaseUrlMode.Automatic && string.IsNullOrWhiteSpace(BaseUrl) && request != null) + { + return string.Create(CultureInfo.InvariantCulture, $"{request.Scheme}://{request.Host.ToUriComponent()}{request.PathBase.ToUriComponent()}/"); + } + return GetFormattedBaseUrl(); + } } diff --git a/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/AppImageTagHelperTest.cs b/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/AppImageTagHelperTest.cs index 966bb069..083aa606 100644 --- a/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/AppImageTagHelperTest.cs +++ b/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/AppImageTagHelperTest.cs @@ -1,11 +1,6 @@ -using System.Threading.Tasks; -using Cuemon.AspNetCore.Razor.TagHelpers.Assets; -using Cuemon.Extensions.AspNetCore.Configuration; +using System; +using System.Threading.Tasks; using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.TestHost; -using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Cuemon.AspNetCore.Razor.TagHelpers; @@ -18,65 +13,34 @@ public AppImageTagHelperTest(ITestOutputHelper output) : base(output) [Fact] public async Task Page_RenderImageTagForAppRole() { - using (var filter = WebHostTestFactory.Create(services => - { - services.AddRazorPages(); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Https; - o.BaseUrl = "nblcdn.net"; - }); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Relative; - o.BaseUrl = "static.cuemon.net"; - }); - }, app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); - })) - { - var client = filter.Host.GetTestClient(); - var result = await client.GetAsync("/AppImageTagHelper"); - var body = await result.Content.ReadAsStringAsync(); + var body = await TagHelperTestFactory.GetBodyAsync("/AppImageTagHelper"); - TestOutput.WriteLine(body); + TestOutput.WriteLine(body); - Assert.Equal(@"", body, ignoreLineEndingDifferences: true); - } + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); } [Fact] public async Task Page_RenderImageTagForAppRole_WithCacheBusting() { - using (var filter = WebHostTestFactory.Create(services => - { - services.AddCacheBusting(); - services.AddRazorPages(); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Https; - o.BaseUrl = "nblcdn.net"; - }); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Relative; - o.BaseUrl = "static.cuemon.net"; - }); - }, app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); - })) + var body = await TagHelperTestFactory.GetBodyAsync("/AppImageTagHelper", useCacheBusting: true); + + TestOutput.WriteLine(body); + + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); + } + + [Fact] + public async Task Page_RenderImageTagForAppRole_UsingCurrentRequestOrigin() + { + var body = await TagHelperTestFactory.GetBodyAsync("/AppImageTagHelper?path=/images/logo.svg", o => { - var client = filter.Host.GetTestClient(); - var result = await client.GetAsync("/AppImageTagHelper"); - var body = await result.Content.ReadAsStringAsync(); + o.BaseUrlMode = TagHelperBaseUrlMode.Automatic; + o.BaseUrl = null; + }, baseAddress: new Uri("https://localhost:7241")); - TestOutput.WriteLine(body); + TestOutput.WriteLine(body); - Assert.Equal(@"", body, ignoreLineEndingDifferences: true); - } + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); } } diff --git a/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/AppLinkTagHelperTest.cs b/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/AppLinkTagHelperTest.cs index 4bd1b9e7..95083304 100644 --- a/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/AppLinkTagHelperTest.cs +++ b/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/AppLinkTagHelperTest.cs @@ -1,11 +1,6 @@ -using System.Threading.Tasks; -using Cuemon.AspNetCore.Razor.TagHelpers.Assets; -using Cuemon.Extensions.AspNetCore.Configuration; +using System; +using System.Threading.Tasks; using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.TestHost; -using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Cuemon.AspNetCore.Razor.TagHelpers; @@ -18,65 +13,89 @@ public AppLinkTagHelperTest(ITestOutputHelper output) : base(output) [Fact] public async Task Page_RenderLinkTagForAppRole() { - using (var filter = WebHostTestFactory.Create(services => - { - services.AddRazorPages(); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Https; - o.BaseUrl = "nblcdn.net"; - }); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Relative; - o.BaseUrl = "static.cuemon.net"; - }); - }, app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); - })) - { - var client = filter.Host.GetTestClient(); - var result = await client.GetAsync("/AppLinkTagHelper"); - var body = await result.Content.ReadAsStringAsync(); + var body = await TagHelperTestFactory.GetBodyAsync("/AppLinkTagHelper"); - TestOutput.WriteLine(body); + TestOutput.WriteLine(body); - Assert.Equal(@"", body, ignoreLineEndingDifferences: true); - } + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); } [Fact] public async Task Page_RenderLinkTagForAppRole_WithCacheBusting() { - using (var filter = WebHostTestFactory.Create(services => + var body = await TagHelperTestFactory.GetBodyAsync("/AppLinkTagHelper", useCacheBusting: true); + + TestOutput.WriteLine(body); + + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); + } + + [Fact] + public async Task Page_RenderLinkTagForAppRole_WithoutConfiguredBaseUrl() + { + var body = await TagHelperTestFactory.GetBodyAsync("/AppLinkTagHelper?variant=stylesheet&path=/css/site.css", o => o.BaseUrl = null); + + TestOutput.WriteLine(body); + + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); + } + + [Fact] + public async Task Page_RenderLinkTagForAppRole_UsingCurrentRequestOrigin() + { + var body = await TagHelperTestFactory.GetBodyAsync("/AppLinkTagHelper?variant=stylesheet&path=css/site.css", o => { - services.AddCacheBusting(); - services.AddRazorPages(); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Https; - o.BaseUrl = "nblcdn.net"; - }); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Relative; - o.BaseUrl = "static.cuemon.net"; - }); - }, app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); - })) + o.BaseUrlMode = TagHelperBaseUrlMode.Automatic; + o.BaseUrl = null; + o.Scheme = ProtocolUriScheme.Http; + }, baseAddress: new Uri("https://localhost:7241")); + + TestOutput.WriteLine(body); + + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); + } + + [Fact] + public async Task Page_RenderLinkTagForAppRole_UsingExplicitBaseUrlWhenAutomaticModeIsEnabled() + { + var body = await TagHelperTestFactory.GetBodyAsync("/AppLinkTagHelper?variant=stylesheet&path=/css/site.css", o => { - var client = filter.Host.GetTestClient(); - var result = await client.GetAsync("/AppLinkTagHelper"); - var body = await result.Content.ReadAsStringAsync(); + o.BaseUrlMode = TagHelperBaseUrlMode.Automatic; + o.BaseUrl = "assets.example.com"; + o.Scheme = ProtocolUriScheme.Https; + }, baseAddress: new Uri("http://localhost:7241")); + + TestOutput.WriteLine(body); + + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); + } + + [Fact] + public async Task Page_RenderLinkTagForAppRole_PreservesFontPreloadAttributes() + { + var body = await TagHelperTestFactory.GetBodyAsync("/AppLinkTagHelper?variant=preload"); + + TestOutput.WriteLine(body); + + Assert.Contains(@"", body, ignoreLineEndingDifferences: true); - } + Assert.Contains(@" - { - services.AddRazorPages(); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Https; - o.BaseUrl = "nblcdn.net"; - }); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Relative; - o.BaseUrl = "static.cuemon.net"; - }); - }, app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); - })) - { - var client = filter.Host.GetTestClient(); - var result = await client.GetAsync("/AppScriptTagHelper"); - var body = await result.Content.ReadAsStringAsync(); + var body = await TagHelperTestFactory.GetBodyAsync("/AppScriptTagHelper"); - TestOutput.WriteLine(body); + TestOutput.WriteLine(body); - Assert.Equal(@"", body, ignoreLineEndingDifferences: true); - } + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); } [Fact] public async Task Page_RenderScriptTagForAppRole_WithCacheBusting() { - using (var filter = WebHostTestFactory.Create(services => + var body = await TagHelperTestFactory.GetBodyAsync("/AppScriptTagHelper", useCacheBusting: true); + + TestOutput.WriteLine(body); + + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); + } + + [Fact] + public async Task Page_RenderScriptTagForAppRole_UsingCurrentRequestOrigin() + { + var body = await TagHelperTestFactory.GetBodyAsync("/AppScriptTagHelper", o => { - services.AddCacheBusting(); - services.AddRazorPages(); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Https; - o.BaseUrl = "nblcdn.net"; - }); - services.Configure(o => - { - o.Scheme = ProtocolUriScheme.Relative; - o.BaseUrl = "static.cuemon.net"; - }); - }, app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); - })) + o.BaseUrlMode = TagHelperBaseUrlMode.Automatic; + o.BaseUrl = null; + }, baseAddress: new Uri("https://localhost:7241")); + + TestOutput.WriteLine(body); + + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); + } + + [Fact] + public async Task Page_RenderScriptTagForAppRole_UsingCurrentRequestOriginAndPathBase_WithCacheBusting() + { + var body = await TagHelperTestFactory.GetBodyAsync("/myapp/AppScriptTagHelper?path=~/js/site.js", o => + { + o.BaseUrlMode = TagHelperBaseUrlMode.Automatic; + o.BaseUrl = null; + }, useCacheBusting: true, baseAddress: new Uri("https://example.com"), pathBase: "/myapp"); + + TestOutput.WriteLine(body); + + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); + } + + [Fact] + public async Task Page_RenderScriptTagForAppRole_UsingLocalHttpExternalOriginWhenConfigured() + { + var body = await TagHelperTestFactory.GetBodyAsync("/AppScriptTagHelper?path=~/js/site.js", o => { - var client = filter.Host.GetTestClient(); - var result = await client.GetAsync("/AppScriptTagHelper"); - var body = await result.Content.ReadAsStringAsync(); + o.BaseUrlMode = TagHelperBaseUrlMode.Automatic; + o.BaseUrl = "localhost:8080"; + o.Scheme = ProtocolUriScheme.Http; + }, baseAddress: new Uri("https://localhost:7241")); - TestOutput.WriteLine(body); + TestOutput.WriteLine(body); - Assert.Equal(@"", body, ignoreLineEndingDifferences: true); - } + Assert.Equal(@"", body, ignoreLineEndingDifferences: true); } } diff --git a/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/Pages/AppImageTagHelper.cshtml b/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/Pages/AppImageTagHelper.cshtml index a5699d18..6a711394 100644 --- a/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/Pages/AppImageTagHelper.cshtml +++ b/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/Pages/AppImageTagHelper.cshtml @@ -1,2 +1,6 @@ @page - \ No newline at end of file +@{ + var src = Request.Query["path"].ToString(); + if (string.IsNullOrWhiteSpace(src)) { src = "cuemon-logo.svg"; } +} + \ No newline at end of file diff --git a/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/Pages/AppLinkTagHelper.cshtml b/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/Pages/AppLinkTagHelper.cshtml index 6bd541af..74308e07 100644 --- a/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/Pages/AppLinkTagHelper.cshtml +++ b/test/Cuemon.AspNetCore.Razor.TagHelpers.Tests/Pages/AppLinkTagHelper.cshtml @@ -1,2 +1,40 @@ @page -