Table of Contents

All Changes in 2sxc and EAV v20

Version 20

2sxc v20.00.00 (2025-06-25)

Warning

2sxc v20 is a MoT Release, containing many breaking changes.

See Breaking Changes in v20 for details.

Highlights

  1. ☒️ The module was moved to /DesktopModules/ToSic.Sxc and was renamed to 2sxc
  2. πŸ’Ύ The entire SQL was reorganized - see 2sxc & EAV Database Changes in v20 for details.
  3. βš™οΈ New CoPilot Code Generator for Models (like TypedItems, but lighter / POCO)
  4. β€οΈβ€πŸ©Ή Introduced many detections of old code to give guidance to users who must fix old code
  5. πŸ₯‡ Create App experience improved to provide apps from the catalog
  6. πŸ₯‡ App Catalog enhanced to manage template apps (which expect to be renamed upon installation) - allowing for more template apps in future
  7. 🦸🏼 New Patrons Performance support tier to use all our performance enhancements
  8. πŸ“– Docs improved to better indicate internal APIs

Enhancements

  1. πŸ’Ύ Database performance enhancements with new indexes and improved code
  2. ✏️ Improved Edit-UI to use in the admin section without saving the entity (for config dialogs which are generated from the schema)
  3. ✏️ Improved Toolbar API .Audience(...) with everyone: true and roleNames and denyRoleNames
  4. πŸ‘±πŸΌ User Service with new .GetCurrentUser()
  5. ⚑ Lots of internal performance improvements, especially in loading, saving and handling data.
  6. πŸ‘¨πŸΌβ€πŸ’» All 2sxc / EAV code is now C# latest #nullable which makes it more robust.
  7. πŸ–ΌοΈ When an imported app has Rich WYSIWYG content with images, the links will be auto-corrected upon edit.
  8. πŸŒͺ️ Visual Query improved with ability to mirror out-streams based on in-streams (for things such as serialization-DataSource etc.)
  9. πŸͺ΅ New features to reduce logging of loading the system or data of Apps, which creates large logs but are rarely used
  10. βœ… Features can now support detailed configuration (used in the new Logging configuration)
  11. πŸ₯·πŸΌ Most internal APIs now clearly moved into .Sys namespaces TODO: - DOCUMENT IN BREAKING

Version Bumps and Other Changes

  1. ☒️ Minimum DNN version is now v9.11.02 (previously v9.6.2)
  2. πŸ–ΌοΈ Updated ImageFlow (the image resizer) to v2.1.0-RC11 from 2.0.0-Preview8
  3. πŸ…°οΈ Update UI to Angular 20 and Angular Material 20

Bugfixes

  1. 🩸 Oqtane fix issue which broke 2sxc because of changes in Oqtane 6.1.2
  2. 🐞 Fix: DataSource RelationshipFilter accidentally filtered out results when the filter was "" (blank) instead of not filtering at all
  3. 🐞 Fix: Images could not be deleted right after uploading, because image resizer kept the file open on the server
  4. 🐞 Fix: When serializing entities with custom configuration, the configuration for the GUID was sometimes ignored
  5. 🐞 Fix: Visual Query preview JSON didn't match serialization configuration.

Internal and Code Hygiene

  1. βœ… Most of the code was reorganized into more DLLs, to better separate concerns and make it easier to maintain / contribute.
  2. βœ… All the code for Eav and 2sxc is now C# latest #nullable which makes it more robust.
  3. βœ… Dropped old .net WebClient and replaced with HttpClient
  4. βœ… Cleanup / improvements around logging.
  5. βœ… Replaced old .net APIs for encryption with latest (reduce warnings)
  6. 🐞 Fix bug which affected developers, where APIs were missing in intellisense because of the EditorBrowsable attribute
  7. βœ… Improved naming of IMetadata from IMetadataOf
  8. βœ… Completely refactored the IBlock implementation and factory for better architecture
  9. βœ… Internal API to debug-dump objects was refactored
  10. βœ… Introduced new ServiceBase<TOptions> for services which need options at startup
  11. βœ… Introduced new SpawnNew() api and Generator<TService, TOptions> for objects expecting a setup.

2sxc v20.00.01 (2025-06-28)

Warning

2sxc v20 is a MoT Release, containing many breaking changes.

See Breaking Changes in v20 for details.

This 20.00.01 has only minor changes.

Enhancements

  1. When configuring views, the selection if it's a list or not will automatically toggle the setting IsList
  2. When upgrading from previous version, the /DesktopModules/ToSIC_SexyContent/system/ folder will be transferred to the new location.
  3. All internal use of global queries was changed to use the correct System. prefix
  4. Any use now of the old prefix Eav.Queries.Global. will throw an error, so you can fix it.
  5. The main lists in the Admin UI were enhanced to show some help text.
  6. UI button colors were improved to be more consistent.

Bugfixes

  1. 🐞 Fix: In 2-3 places some things failed because of list changes; eg. copying a query failed.
  2. 🐞 Fix: Auto-retrieve license from patrons.
  3. 🐞 Fix: In rare cases, changing the field type didn't seem to work.

2sxc v20.00.02 (2025-07-07)

Warning

2sxc v20 is a MoT Release, containing many breaking changes.

See Breaking Changes in v20 for details.

This 20.00.02 has only minor changes.

Enhancements

  1. Admin Features Management - introduce search
  2. Improve help when web.config is missing for Razor files which are used within Html.Partial(...).
  3. Color enhancements in Admin UI, now more consistent.

Bugfixes

  1. 🐞 Edit data (like App Settings) without WYSIWYG caused JS issues
  2. 🐞 Edit view caused some issues
  3. 🐞 Typed API - using Children containing null entry will filter that

Internal Changes

  1. Improved internal namespaces, now everything should be in .Sys
  2. 🩸 Oqtane: client lib does not use the 2sxc sys lib any more (not necessary, speeds up client rendering)
  3. Update Google Maps key to latest version.
  4. Drop complexity with MyServiceBase
  5. Renamed MyServices to Dependencies

2sxc v20.00.03 (2025-07-11)

Warning

2sxc v20 is a MoT Release, containing many breaking changes.

See Breaking Changes in v20 for details.

This 20.00.03 has really nice enhancements, but since we're still stabilizing v20, we are not incrementing the next number yet.

Enhancements

  1. πŸ“€ Introduced ITypedApi and ITypedApiService to improve code quality when using 2sxc in skins or outside of DNN.
  2. πŸ” App.GetQuery(...) now returns an ITypedQuery object which also has GetAll<T> and GetOne<T> just like App.Data
  3. ⚑ Major performance improvements all over, especially for 🦸🏼 Patrons Performance
  4. ⚑ Introduced features to reduce logging during normal operations, which should improve performance and lower memory footprint.
  5. ⚑ Introduced reduced logging during import/save to better debug large imports / apps.
  6. πŸ§‘πŸΌβ€πŸ’» Finally stabilized and released feature to change Edition to switch between live and staging
  7. ⚑ Internal performance improvements when generating toolbars (caching of complex lookups)
  8. πŸ‘©β€πŸ‘¦ Improved .Child(...), .Children(...), .Parent(...) and .Parents(...) to hide related data which is still draft.
  9. πŸ“– Help enhancement for various use cases and better highlighting using emojis such as β€οΈβ€πŸ©Ή and πŸ”—

Bugfixes

  1. 🐞 The first time you added site / global / app settings they would not work until you restarted the system
  2. 🐞 GPS picker had a bug which only affected very old apps (those which had the picker and 2 separate number fields for Long/Lat)
  3. 🐞 Large Apps couldn't be deleted, this is now fixed
  4. 🐞 Edition selection became inaccessible when using incorrect value
  5. 🐞 Fixed API App.Data.GetContentType(...) which only existed in RazorTyped but not in old dynamic APIs.
  6. 🐞 Fixed issue with very old apps not listing razor files in the view configuration

Internal Changes

  1. Dropped old WebApi URLs beginning with app- (documented in the breaking changes)
  2. Removed old .data as data folder for app extensions (in the [AppRoot]/system folder) - now only the protected [AppRoot]/App_Data is supported.
  3. Experimental Tweak API XCustom(prefix, key, value) for testing newer features which are not yet released.
  4. Experimental UI options to modify the behavior and not save data (for dialogs which just show data or only do JS activities)
  5. Experimental UI settings parameter to control this behavior, which is not yet documented.
  6. Experimental dialogSettings toolbar UI to change the UI from saving data to just done (naming and API not final)

2sxc v20.00.04 (2025-08-04)

Warning

2sxc v20 is a MoT Release, containing many breaking changes.

See Breaking Changes in v20 for details.

This 20.00.04 has really nice enhancements, but since we're still stabilizing v20, we are not incrementing the next number yet.

Enhancements

  1. πŸ₯«βš‘ Entire DB Access (read/write) reworked and optimized - this is a major change, but it should not affect any apps.
  2. πŸ₯«βš‘ Almost all DB access now uses non-tracking Entity-Framework queries, which should improve performance.
  3. πŸ₯«βš‘ Introduce Parallel data processing on save - imports now 3-10x faster (Patron Performance)
  4. πŸ₯«πŸ¦ΈπŸΌ Various performance features with DB can now be fine-tuned in features UI.
  5. πŸ…°οΈ App Installer from Template improved
  6. πŸ…°οΈ App Install new but change name/guid to use existing app as if it's a template
  7. πŸ§‘πŸΌβ€πŸ’» Rework SoC dynamic code and Typed Code - separate Metadata, Files, Folders, Fields to be completely independent
  8. πŸ“– Many UIs now have guidance text when opening the dialog

Bugfixes

  1. 🐞 Razor / WebApi: GetService() was missing parameter typeName because in 20.00.04 we thought it's not used.
  2. 🐞 Issue creating new Apps in some cases - especially with new name
  3. 🐞 Bug initializing App still sometimes created multiple Settings/Resources
  4. 🩸 Oqtane: AdamSecurityCheckBasic.CanEditFolder sometimes had a null-ref exception in Oqtane
  5. 🐞 Visual Query: Relationship filter - a modified behavior in v20.00.02 was reverted back to original (empty filter value should still filter for empty)
  6. 🐞 Exotic feature Ghost ContentType hasn't been working for a long time now because name of API parameters changed
  7. 🐞 Fix loading data on large apps - relationships were sometimes duplicated in cache
  8. 🐞 Admin UI - minor issue showing details of shared fields were wrong in some cases
  9. πŸͺ² Minor: when toggling features the section always collapsed
  10. πŸͺ² Minor: Toggling language always sent 2 API requests

Internal Changes

  1. Temporary property .Dyn was removed from ITypedItem
  2. Entity Framework projects are now using C# nullable
  3. Features can now be in multiple licenses (such an LightSpeed in Patron Perfectionist and Patron Performance)
  4. Internal change to Entity object to make it fully immutable
  5. ☒️ DNN: Improved internal dependency injection on ng-edit UIs

2sxc v20.00.05 (2025-08-26)

Warning

2sxc v20 is a MoT Release, containing many breaking changes.

See Breaking Changes in v20 for details.

This 20.00.05 has really nice enhancements, but since we're still stabilizing v20, we are not incrementing the next number yet.

Enhancements

  1. πŸ₯«βš‘ Razor Partial Caching introduced (🦸🏼 Patron Performance)
  2. πŸ₯«βš‘ Razor API @Configuration.PartialCache(...) to configure RazorPartialCaching
  3. πŸͺͺ New UserElevation to determine that caching is enabled/disabled for certain levels
  4. πŸ…°οΈ Admin UI now better indicates clickable areas.
  5. πŸ…°οΈ Admin UI now has more consistent save/close buttons.
  6. πŸ…°οΈ Admin UI now supports ctrl+enter in most dialogs to close and save. #TODOC / #TOBLOG
  7. πŸ§‘πŸΌβ€πŸ’» Install App: Ability to take any app and use it as a template (so give it a new name/GUID) #TODOC
  8. 🩸 Oqtane: Improve install using more SQL to work around problems with incremental updates.
  9. πŸ”¬ Formula: Introduce context.user.roles to let formulas check user roles.
  10. πŸ”¬ Formula: Introduce context.user.isContentEditor to match latest DNN 10 features.

Bugfixes

  1. 🐞 IsAnonymous always returned false since ca. v20.00.00.
  2. 🐞 Data load chunking in Patron-Performance mode had a default of 25k which didn't work well in older SQL servers.
  3. 🐞 When an App is loaded from another site, the path was wrong and file-based content types were not loaded, causing issues.
  4. 🐞 Mobius: System expected encrypted HTTP Net Posts even if not enabled.
  5. 🐞⚑ LightSpeed: Bug that View couldn't enable LightSpeed even if app was "unset" (null) instead of false
  6. 🩸 Oqtane: Bug JS exceptions during dev situation "No interop methods are registered for renderer 1"
  7. 🩸 Oqtane: Bug where old DB tables were recreated after schema update, resulting in old and new tables to be in the DB.
  8. πŸͺ² Minor: Data History: fix date to use UTC (previously used server time.)

Internal Changes

  1. ☒️ DNN: Improved time shown in Insights when a module is being rendered in DNN
  2. 🩸 Oqtane: Update dependencies to Oqtane 6.1.3 and update Asp.Net Core packages to 9.0.5.
  3. 🩸 Oqtane: Sync internal settings-names with the new convention already in use in DNN.

Breaking Changes in EAV and 2sxc v20 - Moment-of-Truth

Important

2sxc v20 is a milestone clean-up release, so it contains a lot of breaking changes.

This is the Moment of Truth where you see if you accidentally used internal or very old APIs.

These changes should only affect you, if you are accessing exotic/internal APIs, or if you have some extremely old/deprecated code.

See also: MoT Policy (Moment of Truth)

Note that we marked the breaking changes like this

  • ⚠️ things which may affect you
  • ⬇️ things which are extremely unlikely to affect you
Tip

Note that the focus of breaking changes is on the Razor code. But there are also 2 small breaking changes in Formulas.

Highlights

Tip

Despite this being a breaking change, we want to emphasize that much of this is great news. It removes a lot of old cruft, and cleans up some history such as "SexyContent".

These changes only affect you, if you were doing some really nasty things, such as accessing the DB directly.

  1. ⚠️ All SQL tables and restructured - see 2sxc & EAV Database Changes in v20

  2. ⚠️ In Dnn, the module is now installed in /DesktopModules/ToSic.Sxc/ instead of /DesktopModules/ToSic_SexyContent/
    This could affect you, if you had direct links to

  3. ⚠️ In Dnn we stop auto-creating a web.config file in the /2sxc/ folder, so Razor files will no longer automatically use the old base class SexyContentWebPage. This should not affect you, you're installing old Apps in newer DNNs.
    πŸ”¨ see Fix Breaking Change Stop Razor from Default to SexyContentWebPage in v20

  4. ⬇️ The minimum Dnn version for v20 is now Dnn 9.11.02 (previously it was 9.6.1)
    This is because older DNNs have important security issues, and we want to force people to update.
    As of now, 2sxc v20 will still run on older DNNs, but we will not support it or test it.

  5. ⬇️ The image resizer only includes the 64 bit binaries, the 32 bit binaries were removed. This makes the distribution smaller, and I don't think anyone is using 32 bit servers anymore.

  6. ⬇️ All code was restructured to create smaller, more focused assemblies.
    This should not affect you, but if you were using some very old code, it may have been moved to a different assembly. This can affect you if you were using compiled code which referenced the old assemblies (not common).

  7. ⬇️ Most internal APIs were moved into Sys namespaces, so it's easier to see if you're using internal APIs.
    This should not affect you, unless you were already using internal APIs.

  8. ⬇️ In Dnn, the modules name is now 2sxc instead of SexyContent

Breaking IEntity API Changes (Razor)

Tip

If your code just used the normal DynamicEntity or TypedEntity / Items APIs, you are not affected by these changes.

But in rare cases, especially in older Apps, some workarounds were used to access the IEntity interface directly.

This is usually done by first running AsEntity(someObject) to get the IEntity underlying data.

  1. ⚠️ A very old interface ToSic.Eav.Interfaces.IEntity has been removed, please use ToSic.Eav.Data.IEntity instead.
    Some very old code may have used this to work around LINQ limitations. Just use the new one, it's the same thing (but with fewer APIs, according to clean-up below).
    We've added some error handling to find out if this is the problem you have, and should lead you to this page.

  2. ⚠️ IEntity has object Get(name, ...) and 2 special Get<TVal>(...) methods to get a value and convert it to string, int etc. The special typed <TVal> variants were moved into extension methods.
    Normally this should not affect you, if you are @using ToSic.Eav.Data in your code, since it will just work. If you did this is a more exotic way, add the @using ToSic.Eav.Data to your code, and it will work again.

  3. ⚠️ IEntity had various GetBestValue(...) APIs which were removed. We believe that about 2-3% of all code used this, so it may affect you. πŸ”¨ see Fix Breaking Change drop old GetBestValue API in v20

  4. ⬇️ APIs on IEntity were modified

    1. .Children(...) and .Parents(...) now return IEnumerable<IEntity> instead of List<IEntity>.
      This will only affect you if you are using .Count on the result, in which case you should use .Count() instead.
  5. ⬇️ Old, deprecated APIs IEntity were removed.
    These have not worked properly for many years.
    We've added some error handling to find out if this is the problem you have, and should lead you to this page.

    1. object GetBestValue(string attributeName, bool resolveHyperlinks) - didn't work for a long time, is being removed

    2. TVal GetBestValue<TVal>(string name, string[] languages, bool resolveHyperlinks) - didn't work for a long time, is being removed

    3. object GetBestValue(string attributeName, string[] languages, bool resolveHyperlinks) - didn't work for a long time, is being removed

    4. object Value(string field, bool resolve = true) - didn't work for a long time, is being removed

    5. T Value<T>(string field, bool resolve = true) - didn't work for a long time, is being removed

  6. ⬇️ Some unofficial APIs on IEntity were removed

    1. object PrimaryValue(string attributeName)
      The term PrimaryValue was an idea which we never pursued further. please just use Get(...) instead

    2. TVal PrimaryValue<TVal>(string attributeName)
      The term PrimaryValue was an idea which we never pursued further. please just use Get(...) instead

    3. object Value(string attributeName)
      The term Value was an idea which we never pursued further. please just use Get(...) instead

    4. TVal Value<TVal>(string attributeName)
      The term Value was an idea which we never pursued further. please just use Get(...) instead

  7. ⬇️ An API giving access to the ContentType Description IContentType.Metadata.Description were removed We don't believe anyone used this.

Other Breaking Razor API Changes (Dnn only)

  1. ⚠️ The behavior to auto-load jQuery for very old Razor base classes was removed.
    A long time ago 2sxc accidentally loaded jQuery automatically in DNN.
    In those days, jQuery was used a lot. We stopped doing this for newer Razor base classes, but preserved the behavior for very old Razor base classes.
    This was removed in v20, so if you were using the old Razor base classes, you will need to add jQuery manually.
    Note: code for this was commented out with #RemovedV20 #OldDnnAutoJQuery.

  2. ⚠️ Three old APIs on old Razor Base classes such as SexyContentWebPage were removed. All have been deprecated since v12.
    They were originally meant to use the same Razor file to also create a WebApi and fill the DNN search index, but was deprecated a long time ago.

    1. Purpose - this was meant to tell Razor if it should prepare data for search or for view.
    2. CustomizeSearch(...) this was meant to customize the data for the search index. The functionality was moved to separate code many years ago.
    3. CustomizeData(...) this was a patchy way to specify the data for the razor template.
  3. ⚠️ The SexyContentWebPage had a List property which provided Element objects to loop through.
    They were deprecated since v12, and replaced with the new Razor base classes which are much better. If you were using these, please switch to the new Razor base classes and use the more modern approaches such as MyItem, MyItem.Presentation, Content, etc. πŸ”¨ To fix, see Fix Breaking Change List of Elements in v20. Note: code for this was commented out with #RemovedV20 #Element.

  4. ⬇️ There is a /system folder in the DesktopModules which had extensions. Each could have a .data folder - this must now be App_Data.
    This is probably not an issue, as we will auto-rename this during the upgrade of v20.00.01

  5. ⚠️ Every App can have a similar /system folder. Each could have a .data folder - this must now be App_Data.
    This is rarely used, but you would have to manually rename this folder to App_Data if you had it.

  6. ⚠️ DNN had some very old (pre v8) WebApi routes like app-content, app-query and app-api which were removed.
    If you had these in your code, please use the same route, just without the app- prefix.

  7. ⬇️ An old interface ToSic.Sxc.Blocks.IRenderService was removed, since it's been superseded by ToSic.Sxc.Services.IRenderService. We believe it was used in 2-3 v12 Apps, so if you encounter this, just switch to ToSic.Sxc.Services.IRenderService instead.

  8. ⬇️ An internal interface called ToSic.Sxc.Data.IEntityLight was removed
    We don't believe anyone used this, but if you did, please use ToSic.Eav.Data.IEntity instead.

  9. ⬇️ A very old interface called SexyContent.Interfaces.IDynamicEntity was removed.
    If you really had this in your code, please use ToSic.Sxc.Data.IDynamicEntity instead.

  10. ⬇️ Some internal objects were consolidated, such as IAttributeBase which nobody should have used anyway
    We don't believe anyone used this.

  11. ⬇️ lots of internal namespaces and classes/interfaces were renamed, including but not limited to:

    1. DynamicEntity.GetEntityValue(string name) (removed)
  12. ⬇️ An old API used by some of the first Mobius Apps used App.Data.Cache.GetContentType.
    This has been obsolete since v10 and is now removed in v20.
    We suggest you use a newer Mobius App or if you're really desperate, see πŸ”¨ Fix Breaking Change Removal of Cache on IAppData in v20.

  13. ⬇️ An old internal interface called ToSic.SexyContent.IAppAndDataHelpers was removed.
    It was implemented by ToSic.SexyContent.Razor.SexyContentWebPage and ToSic.SexyContent.WebApi.SxcApiController. The APIs on it still work, but the interface was removed; you should not notice the clean-up. See Fix Breaking Change Dnn Files / Folders in v20

Breaking Formulas API Changes

V1 form.runFormulas() Was Removed

The V1 formulas were not async, so they had a patchy solution for using formulas which requested data from the server. The old solution was to use fetch and in the promise, call form.runFormulas() to retrigger the formulas after the data was loaded.

2sxc 16 in early 2023 introduced V2 formulas which can return a promise. This will automatically trigger recalculations when the promise resolves, and allows for better control over what happens (like if the same formula should run again, or not).

Since v16 was released, any use of the old form.runFormulas() resulted in a warning in the console.

In v20, this method was disabled showing a JS error. If you were using it, please remove it and use the new V2 formulas instead.

Internal Formula Changes

An internal API which placed some experimental commands in the formula calls were moved to the context. Since it was only used internally, it should not affect anyone.

Other Changes

  1. ⬇️ Custom extensions (such as custom input fields) in the /system folder should place their data in the /system/[ext-name]/App_Data/system-custom/ path.
    Previously the path /system/[ext-name]/.data/ was also supported, but this is now removed.

  2. ⬇️ All system queries which are called System.Whatever previously also supported being called by Eav.Queries.Global.Whatever.
    This is now removed, so you should only use System.Whatever to call global queries.

  3. ⬇️ The DependenciesClass was previously called MyServices but it was very unclear, so it was renamed. ToSic.Eav.Data.IEntity.
    This is a breaking change, but we don't believe anyone used this interface directly, except in custom DataSources - where we kept the old name for compatibility.

  4. ⬇️ The IContentType had a .ContentTypeId which should only be .Id. The old .ContentTypeId was removed (deprecated since v13).
    This is a breaking change, but we don't believe anyone used this property directly.

  5. ⬇️ The IContentType had a .StaticName which should only be .NameId. The old .StaticName was removed (deprecated since v13).
    This is a breaking change, but we don't believe anyone used this property directly.

  6. ⬇️ Previously the APIs .Child(...), .Parent(...), .Children(...), and .Parents(...) on ITypedItem would return the related data without checking for publishing. Now it will check for publishing and only show draft children/parents to editors (v20.00.03).
    This is a breaking change, but we don't believe draft-children were used much.

  7. ⬇️ The ITypedItem had a .Dyn property which was removed (v20.00.04).
    It was a temporary addition (and always marked as such) thought to help in migrating code. But we're afraid people may use it and leave it in, so we decided it's best to completely remove it.