Gulla.Optimizely.DdsExplorer
1.0.0
See the version list below for details.
dotnet add package Gulla.Optimizely.DdsExplorer --version 1.0.0
NuGet\Install-Package Gulla.Optimizely.DdsExplorer -Version 1.0.0
<PackageReference Include="Gulla.Optimizely.DdsExplorer" Version="1.0.0" />
<PackageVersion Include="Gulla.Optimizely.DdsExplorer" Version="1.0.0" />
<PackageReference Include="Gulla.Optimizely.DdsExplorer" />
paket add Gulla.Optimizely.DdsExplorer --version 1.0.0
#r "nuget: Gulla.Optimizely.DdsExplorer, 1.0.0"
#:package Gulla.Optimizely.DdsExplorer@1.0.0
#addin nuget:?package=Gulla.Optimizely.DdsExplorer&version=1.0.0
#tool nuget:?package=Gulla.Optimizely.DdsExplorer&version=1.0.0
Gulla.Optimizely.DdsExplorer for CMS 12
This is the readme for the CMS 12 version, the version for CMS 13 is over here.
A Dynamic Data Store explorer for Optimizely CMS 12. Browse DDS stores, see their definitions, view and edit an item as JSON, and delete items, empty stores or delete stores entirely, from the settings area of the CMS.
Which version do I need?
| Package version | Optimizely CMS | .NET |
|---|---|---|
| 1.x (this branch) | CMS 12 | .NET 8 |
| 2.x | CMS 13 | .NET 10 |
The two lines are feature-identical. Only the CMS shell integration differs.
Requirements
.NET 8
Optimizely CMS 12 with
EPiServer.CMS.UI.Core12.22.0 or later.12.22.0 is the first release with the shell API the menu item is registered through (
IEPiProductMenuProvider); earlier 12.x releases do not compile.
Installation
dotnet add package Gulla.Optimizely.DdsExplorer
In Program.cs:
builder.Services.AddDdsExplorer();
Usage
Log in as an administrator, open Settings, and pick DDS Explorer under Tools.
- Stores — every store with its item count and number of properties, filterable by name. Stores that look like they belong to Optimizely are badged System.
- A store — its definition (each property's name, CLR type, mapping kind and whether it can be edited here) and its items, 50 per page. Paging runs in SQL, so large stores are fine.
- An item — click its Id to open it as JSON. From there it can be edited or deleted.
Deleting
| Action | What it does | Confirmation |
|---|---|---|
| Delete item | Deletes one item | Confirm dialog |
| Delete selected | Deletes the items ticked on the current page | Confirm dialog |
| Empty store | Deletes every item, keeps the store and its definition | Type the store name |
| Delete store | Deletes the store, its definition and every item | Type the store name |
Empty store is usually the safer choice: the code that owns the store keeps working, because the store does not have to be recreated with its mapping.
System stores get an extra warning but are never blocked. Deleting one can break the site.
Editing
⚠️ Editing raw DDS data can corrupt it. The code that owns a store expects its data in a particular shape, and a value that is valid for its type can still break that code. There is no undo.
Saving is strict, and a save that breaks any rule is rejected as a whole:
- The document must have exactly the store definition's properties plus
Id— none added, none removed. Keys are case-sensitive. Idcannot be changed.- Every changed value must convert to the property's declared CLR type. Numbers are JSON numbers;
Guid,DateTime(ISO 8601, e.g.2026-09-29T12:00:00.0000000Z),Identityandcharare strings; enums are names (a defined number is accepted too). - Only inline properties of simple types (string, bool, numbers,
Guid,DateTime,Identity, enums, and their nullable forms) can be changed. Collections, references and properties whose type can no longer be loaded are read-only: they may be left as they are, but any change to them is rejected.
The item is saved the way its owner would save it: loaded as its own CLR type, only the changed properties set, then saved. References and collections are left exactly as they were. An item whose CLR type cannot be loaded cannot be edited at all.
Broken stores
A store whose definition no longer loads is badged Broken in the list.
Such a store opens in raw mode, read straight from the DDS tables: the definition with its types as stored text, the items from the store's SQL view, and collections and references as their rows in tblBigTableReference. Neither items nor the store can be emptied, but the store can be deleted, which the explorer does by name, without loading the definition.
Items in raw mode can still be edited, within narrower limits: only inline properties whose stored type still loads (typically string, numbers, bool, DateTime, Guid and nullable forms) can change, and the new values are written straight to their columns in tblBigTable, in one transaction, the same way DDS's own save does. Values are shown and edited as the database holds them — an enum as its number, a DateTime without its kind. ItemType, collections, references, Identity and binary values are read-only. The same strict rules as above apply otherwise, including the check that the item has not changed since it was opened.
Logging
Every edit and delete is logged at Information level through ILogger, with the user, the store and the item Id(s); an edit also names the properties it changed. No values are logged, neither before nor after the change, so nothing a store holds, personal data included, ends up in the site log. That also means the log cannot restore a bad edit. Take a database backup first if you may need to go back.
If the site's minimum log level is above Information, these entries are dropped. To keep them, lower the level for the add-ons own category:
{
"Logging": {
"LogLevel": {
"Gulla.Optimizely.DdsExplorer": "Information"
}
}
}
Configuration
builder.Services.AddDdsExplorer(options =>
{
options.PageSize = 100;
options.SystemStorePrefixes = ["EPiServer.", "Optimizely.", "MyCompany.Internal."];
});
or in appsettings.json:
{
"Gulla": {
"DdsExplorer": {
"PageSize": 100,
"SystemStorePrefixes": ["EPiServer.", "Optimizely.", "MyCompany.Internal."]
}
}
}
SystemStorePrefixes replaces the default list, so include any default prefixes you want to keep.
| Option | Default | Meaning |
|---|---|---|
PageSize |
50 |
Items per page, 1–1000. |
SystemStorePrefixes |
EPiServer., Episerver., Optimizely., Mediachase., EPiServer_, Episerver_, Optimizely_, Forms., Find. |
Store name prefixes badged System (matched case-insensitively). Setting it replaces the whole list. |
Authorization
By default the explorer is open to CmsAdmins, Administrators and WebAdmins, through a policy named DdsExplorerAdmin. To change it, register your own policy with that name:
builder.Services.AddDdsExplorer(authorization =>
{
authorization.AddPolicy("DdsExplorerAdmin", policy => policy.RequireRole("CmsAdmins"));
});
A policy you define yourself always takes precedence over the default, wherever it is registered.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. |
-
net8.0
- EPiServer.CMS.Core (>= 12.15.0 && < 13.0.0)
- EPiServer.CMS.UI.Core (>= 12.22.0 && < 13.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
First release.