Storage path mapping

Xperience by Kentico uses a storage path registry to manage how application file system paths are routed to file system providers. Each Xperience module registers the file system paths it uses and classifies them by a path type. A mapping method reads these registrations and routes each path to the correct storage provider based on the hosting environment.

To activate storage path mapping, call the appropriate extension method in Program.cs for your hosting scenario. See Choose a mapping approach for details.

All system paths (media libraries, content item assets, form file attachments, AIRA files, and others) are registered by Xperience modules during startup. You only need to register custom paths if your application stores files in additional directories.

How storage path mapping works

The mapping system consists of two parts:

  1. Path registration – Each Xperience module declares which file system paths it uses and classifies them by type (SharedPersistent, SharedTemp, or LocalOnly). These declarations are collected in a central path registry (IStoragePathRegistry).
  2. Path mapping – A mapping method reads all registered paths and maps each to the correct storage provider. The mapping behavior depends on the hosting environment and the path type.

All file I/O in Xperience goes through the CMS.IO abstraction layer, which delegates to the configured storage provider for each path. Application code reads and writes files through CMS.IO, and the underlying provider handles the rest. See Files API and CMS.IO for details.

Path types

The PathType enum classifies registered paths so the mapping system knows how to route them:

Path type

Description

Mapping behavior

Examples

SharedPersistent

Data shared across all instances with long-term persistence.

Mapped to persistent shared storage (e.g., Azure Blob Storage).

Content item assets, media library files, form file attachments, AIRA files

SharedTemp

Temporary data shared across instances but not requiring long-term persistence.

Mapped to shared file system storage.

Content synchronization files

LocalOnly

Instance-local data never shared across instances.

Uses the default local file system provider (no external mapping).

Caches, temporary files

On Azure App Service (both SaaS and private cloud), all instances share the same local file system (an Azure-managed file share). Because of this, LocalOnly and SharedTemp paths both physically reside on storage accessible to all instances – the path type distinction has no practical effect on file accessibility between instances. The distinction matters in environments where each instance has a truly separate local disk (such as on-premises instances or container deployments without shared volumes), where SharedTemp paths are explicitly mapped to shared storage while LocalOnly paths remain instance-local.

Choose a mapping approach

The mapping approach depends on your hosting environment:

Hosting scenario

Action

Details

Local single-instance development

No mapping needed.

All files stay on local disk via the default provider.

SaaS

Call AddXperienceCloudStoragePathMapping().

See Azure Blob storage for SaaS.

Private cloud (Azure App Service)

Call AddAppServiceStoragePathMapping().

See Azure Blob storage for private cloud.

Other private cloud (Amazon S3, on-premises, etc.)

Create a custom mapping module.

See Custom file system providers. For Amazon S3-specific configuration, see Amazon S3.

System-registered paths

Xperience modules register the following paths during application startup:

Path

Path type

Identification method

Description

Media library files

SharedPersistent

IsMediaLibraryPath()

Binary files for media libraries (~/assets/media).

Content item assets

SharedPersistent

IsContentItemAssetPath()

Files stored in content item asset fields (~/assets/contentitems).

Content item asset temp

SharedTemp

IsContentItemAssetTempPath()

Temporary files for content item asset processing.

Form file attachments

SharedPersistent

IsBizFormFilesPath()

Files uploaded via form components (~/assets/bizformfiles).

Form file temp

SharedTemp

IsBizFormTempFilesPath()

Temporary files for form uploads.

AIRA files

SharedPersistent

IsAiraPath()

Files uploaded by the AIRA feature (~/assets/aira).

Synchronization data

SharedTemp

IsSynchronizationPath()

Content synchronization data files (~/assets/synchronizations).

Temporary files, caches, CI repository, event logs, wwwroot

LocalOnly

Instance-local files that are not mapped to external storage.

The Identification method column lists extension methods from the CMS.IO.Extensions namespace. Use these methods in per-path configuration callbacks (such as CreateProviderForPath or ConfigureContainerForPath) to identify system paths.

Register custom paths

If your application stores files in custom directories beyond what modules register, register them so the mapping system includes them.

C#
Program.cs


using CMS.IO;

builder.Services.AddStoragePathRegistration("~/custom-uploads", PathType.SharedPersistent);
builder.Services.AddStoragePathRegistration("~/custom-temp", PathType.SharedTemp);

Register paths in custom modules

If you develop custom Xperience modules that store files on the file system, register paths in the module’s OnPreInit method:

C#
Custom module


using CMS;
using CMS.DataEngine;
using CMS.IO;

[assembly: RegisterModule(typeof(MyCustomModule))]

public class MyCustomModule : Module
{
    public MyCustomModule()
        : base(nameof(MyCustomModule)) { }

    protected override void OnPreInit(ModulePreInitParameters parameters)
    {
        base.OnPreInit(parameters);

        parameters.Services.AddStoragePathRegistration("~/assets/my-custom-data", PathType.SharedPersistent);
        parameters.Services.AddStoragePathRegistration("~/assets/my-custom-temp", PathType.SharedTemp);
    }
}

Registered custom paths participate in the mapping system alongside system paths. Choose the appropriate path type based on the nature of the stored data.

Best practices

  • Register all custom paths – If your application stores files in directories outside what modules manage, always register them with AddStoragePathRegistration(). Unregistered paths are not included in automatic mapping, and files may be lost during redeployment or slot swaps.
  • Choose the correct path type for each registered path based on the nature of the stored data.
  • Use path identification methods in callbacks – When configuring per-path overrides (via CreateProviderForPath, ConfigureContainerForPath, or similar callbacks), use extension methods from the CMS.IO.Extensions namespace (for example, IsMediaLibraryPath(), IsBizFormFilesPath()) to identify system paths. Avoid comparing against path strings directly, as paths may change between versions.