Releases: RWS/dxa-core
DXA 2.4 — .NET 8 support
DXA 2.4 for .NET 8
DXA 2.4 is the first release of the Digital Experience Accelerator running on .NET 8. The framework has been ported from the .NET Framework 4.8 implementation that previously lived in RWS/dxa-web-application-dotnet and RWS/dxa-modules, and consolidated into the new RWS/dxa-core monorepo.
If you are running DXA 2.3 on .NET Framework 4.8 today, this is a major upgrade. Read the Migration from DXA 2.3 (.NET 4.8) and Breaking changes sections carefully before adopting.
CM compatibility: No changes required on the Content Manager side. Continue using DXA 2.3 TBBs and continue publishing DXA R2 JSON.
Highlights
- .NET 8 throughout. Framework, modules, and example web app target
net8.0, .NET Framework 4.8 is no longer supported. - ASP.NET Core MVC replaces classic ASP.NET MVC 5. Middleware pipeline, built-in dependency injection, async-first I/O, IIS in-process or Kestrel hosting.
- Monorepo consolidation. What previously shipped as
dxa-web-application-dotnet+dxa-modulesis now one repository with seven components, each releasable as an independent NuGet package. - License change: MIT → Apache-2.0 for all packages.
- NuGet packages on nuget.org:
Supported modules
| Module | NuGet | Status |
|---|---|---|
| Core | Tridion.Dxa.Module.Core |
Supported |
| Search | Tridion.Dxa.Module.Search |
Supported |
| Dynamic Documentation | Tridion.Dxa.Module.DynamicDocumentation |
Supported |
| Experience Optimization (XO) | — | Not supported in DXA 2.4 / .NET 8 |
If your DXA 2.3 application depends on the XO module, plan accordingly before upgrading.
Project restructuring & assembly renames
The .NET Framework version was split across multiple repositories and many assemblies. On .NET 8 it consolidates into a single monorepo at RWS/dxa-core:
Repository layout
| Component | NuGet package | Was previously in |
|---|---|---|
dxa-framework-datamodel |
Tridion.Dxa.Framework.DataModel |
Embedded inside dxa-web-application-dotnet |
dxa-pca-client-net |
Tridion.Dxa.Api.Client |
Standalone library, now versioned with DXA |
dxa-framework-mvc-net |
Tridion.Dxa.Framework |
Sdl.Web.Mvc + Sdl.Web.Tridion (+ ModelService, Common) in dxa-web-application-dotnet |
dxa-module-core-net |
Tridion.Dxa.Module.Core |
Sdl.Web.Modules.Core from dxa-modules |
dxa-module-dynamicdocumentation-net |
Tridion.Dxa.Module.DynamicDocumentation |
Sdl.Web.Modules.DynamicDocumentation from dxa-modules |
dxa-module-search-net |
Tridion.Dxa.Module.Search |
Sdl.Web.Modules.Search from dxa-modules |
dxa-web-application-mvc-net |
(sample app — not published) | The web project from dxa-web-application-dotnet |
Assembly renames
Multiple .NET Framework assemblies were consolidated into Tridion.Dxa.Framework:
| Old (.NET 4.8) | New (.NET 8) |
|---|---|
Sdl.Web.Common |
folded into Tridion.Dxa.Framework |
Sdl.Web.ModelService |
folded into Tridion.Dxa.Framework |
Sdl.Web.Mvc |
folded into Tridion.Dxa.Framework |
Sdl.Web.Tridion |
folded into Tridion.Dxa.Framework |
Sdl.Tridion.Api.Client |
renamed to Tridion.Dxa.Api.Client |
Sdl.Dxa.DataModel |
renamed to Tridion.Dxa.Framework.DataModel |
Namespaces inside each assembly are preserved (Sdl.Web.Common.*, Sdl.Web.Mvc.*, etc.) so most using directives in custom code keep working — you'll just be referencing different DLLs.
A single release script (Release-Dxa.ps1 at the repo root) drives the full dependency-ordered publish chain. See the README "Release" section.
Migration from DXA 2.3 (.NET 4.8)
This release is a runtime + framework migration, not just a version bump. Every public API surface that depended on System.Web has been replaced.
1. Configuration: web.config → appsettings.json
The application setting model has changed entirely. web.config is now used only for IIS module / handler bindings; runtime configuration moves to appsettings.json.
Application settings move under a Dxa section:
{
"Dxa": {
"Services": { "Discovery": "http://your-discovery-service" },
"OAuth": {
"Enabled": true,
"ClientId": "cduser",
"ClientSecret": "..."
},
"Caching": { "ViewModelCaching": true },
"DefaultModule": "Core",
"AdminRefreshEnabled": true
},
"SdlWebDelivery": {
"Caching": {
"DefaultHandler": "regularCache",
"Enabled": true,
"Handlers": {
"regularCache": { "Type": "DefaultMemCacheHandler", "Policy": { "AbsoluteExpiration": "300" } }
},
"Regions": {
"PageModel": { "CacheName": "regularCache" }
}
}
}
}2. Dependency injection: Unity → built-in .NET DI
Unity.config is replaced by service registrations in Startup.cs. The provider mapping:
| .NET 4.8 (Unity.config) | .NET 8 (Startup.cs) |
|---|---|
<type type="ILogger" mapTo="NLogLogger"> |
services.AddSingleton<ILogger, DefaultLogger>(); |
<type type="ICacheProvider" mapTo="DefaultCacheProvider"> |
services.AddSingleton<ICacheProvider>(p => new KeylockCacheProvider(new DefaultCacheProvider(...))); |
<type type="IBinaryProvider" mapTo="GraphQLBinaryProvider"> |
services.AddTransient<IBinaryProvider, DefaultBinaryProvider>(); |
<type type="IMediaHelper" mapTo="BaseMediaHelper"> |
services.AddTransient<IMediaHelper, BaseMediaHelper>(); |
<type type="IContentProvider" mapTo="GraphQLContentProvider"> |
services.AddTransient<IContentProvider, DefaultContentProvider>(); |
<type type="IModelServiceProvider" mapTo="GraphQLModelServiceProvider"> |
services.AddTransient<IModelServiceProvider, DefaultModelServiceProvider>(); |
<type type="ILinkResolver" mapTo="GraphQLLinkResolver"> |
services.AddTransient<ILinkResolver, DefaultLinkResolver>(); |
<type type="INavigationProvider" mapTo="StaticNavigationProvider"> |
services.AddTransient<INavigationProvider, StaticNavigationProvider>(); |
<type type="ILocalizationResolver" mapTo="GraphQLLocalizationResolver"> |
services.AddTransient<ILocalizationResolver, DefaultLocalizationResolver>(); |
The bulk of the registrations are handled for you by services.AddDxa(Configuration); custom providers go alongside.
3. Middleware: HTTP modules → ASP.NET Core middleware
Startup.Configure():
app.UseForwardedHeaders();
app.UseStaticFiles();
app.UseRouting();
// DXA middleware
app.UseMiddleware<ADFContextMiddleware>(
Configuration.GetSection("AmbientConfig").Get<AmbientDataConfig>());
app.UseDxa();
app.UseEndpoints(endpoints => {
endpoints.ConfigureDxaEndpoints(serviceProvider);
});DxaMiddleware resolves the Localization, initializes WebRequestContext, and serves static binary content.
4. Views
Partial views
@* Old (.NET 4.8) *@
@Html.Partial("Partials/Teaser")
@* New (.NET 8) *@
@await Html.PartialAsync("Partials/Teaser")Resource localization
@* Old (.NET 4.8) *@
@Html.FormatResource("core.visitUsSocialLinkTitle", link.Tag.DisplayText)
@* New (.NET 8) — inject IStringLocalizer and pass it to FormatResource *@
@inject Microsoft.Extensions.Localization.IStringLocalizer<TridionStringLocalizer> Localizer
@Html.FormatResource(Localizer, "core.visitUsSocialLinkTitle", link.Tag.DisplayText)Developer-mode check
@* Old *@
@if (WebRequestContext.IsDeveloperMode)
@* New *@
@if (WebRequestContext.Current.IsDeveloperMode)Views\web.config → _ViewImports.cshtml
The per-area web.config that declared default <add namespace="..."> is replaced by an _ViewImports.cshtml:
@* Areas/Core/Views/_ViewImports.cshtml *@
@using Sdl.Web.Modules.Core
@using Sdl.Web.Mvc.Configuration
@using Sdl.Web.Mvc.Html
@using Sdl.Web.Common.Models
@using Sdl.Web.Common.Configuration
@using Sdl.Web.Common.Extensions
@using Sdl.Web.Modules.Core.Models5. Caching
DXA's per-region cache configuration in appsettings.json (SdlWebDelivery:Caching) is unchanged in shape. The implementation (DefaultCacheProvider) now uses IMemoryCache and IDistributedCache from the .NET runtime.
For Redis, register it in ConfigureServices:
services.AddStackExchangeRedisCache(options => {
options.Configuration = "your-redis-host:6379";
options.InstanceName = "DXA-regular";
});Session storage is now opt-in Redis via SdlWebDelivery:Caching:Session:UseRedis (defaults to in-memory). Suitable for single-instance deployments without Redis. See Startup.cs for the gating pattern.
6. Logging
Logs flow through Microsoft.Extensions.Logging. NLog integration is provided in the example web app via NLog.Extensions.Logging and NLog.Web.AspNetCore. The DXA Log static class (Sdl.Web.Common.Logging.Log) is still available and writes through the configured logger factory.