A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

CMS 12+Content Graph: JSON casing mismatch breaks UI in add-ons (Forms, Admin/Contacts/Organization) — suspected formatter conflict with System.Text.

Vote:
 

In multiple CMS 12 solutions, we observe that when Content Graph is used together with additional packages (e.g., Optimizely Forms, Admin shell features like Contacts/Organization), certain endpoints return JSON in PascalCase while the UI expects camelCase. This causes data-binding and logic failures in the affected UIs.

Environment (representative)

  • Hosting: Optimizely DXP (PaaS)

  • CMS: 12.x (one working baseline on 12.33.1; another project on latest packages as of Dec 2025 shows the issue)

  • Add-ons: Content Graph, Optimizely Forms (also seen in Admin/Contacts/Organization)

  • Serialization: System.Text.Json (default) and a custom ExtendedNewtonsoftJsonOutputFormatter present in the app

Symptoms

  • API endpoints like GetUserPermission (Contacts/Organization) or Forms-related endpoints return PascalCase properties.

  • The corresponding UI components expect camelCase, resulting in broken behavior (data not shown, logic failing, etc.).

  • In a different project without the issue, the same endpoints respond with camelCase and the UI works.

Repro (high-level)

  1. Open CMS Admin and navigate to a screen that consumes permissions/forms JSON (e.g., Contacts/Organization permission view or specific Forms UI).

  2. Inspect the network response.

  3. In the affected project, properties are PascalCase; in the working project, camelCase.

  4. Observe UI malfunction only when PascalCase is returned.

Analysis / Suspected cause

  • The project includes a custom Newtonsoft output formatter. Under certain conditions, the response pipeline appears to fall back to Newtonsoft, emitting PascalCase (matching C# property names), even though CMS defaults to System.Text.Json.

  • This aligns with the fix note in CMS-43203 (“Admin shell controllers now default to System.Text.Json”). Our hypothesis: a registration/precedence conflict (formatter order or module configuration) causes specific controllers to bypass System.Text.Json in some setups, especially when Content Graph + add-ons are present.

Workarounds that unblock us

  1. Force System.Text.Json for the affected model(s):

 
// Example: restores camelCase for the model used by the UI services.UseSystemTextJsonSerialization(typeof(PermissionController).Assembly);
  1. If Newtonsoft must remain for selected controllers, enforce camelCase there too:

 
services.AddControllers() .AddNewtonsoftJson(o => { o.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(); });
  1. Formatter hygiene:

    • Keep Admin/Forms controllers on System.Text.Json wherever possible.

    • Review any module/config entries (e.g., preferredUiJsonSerializerType) and formatter registration order that might prioritize Newtonsoft for UI endpoints.

What we tried / comparison

  • Project A (works): CMS 12.33.1, default UI behavior → responses are camelCase; no UI breakage.

  • Project B (issues): latest packages (Dec 2025), Content Graph + Forms + custom Newtonsoft formatter → some endpoints return PascalCase; UI breaks.

  • Adding UseSystemTextJsonSerialization(typeof(PermissionsController).Assembly) immediately restores camelCase and fixes the UI.

Questions to the community / Optimizely

  1. Can others reproduce this with CMS 12 + Content Graph + Forms (and/or Admin/Contacts/Organization) when a custom Newtonsoft formatter is present?

  2. Is there official guidance to guarantee that System.Text.Json remains the effective serializer for Admin/Forms controllers even if Newtonsoft is registered for other areas?

  3. Is this a known regression related to CMS-43203, or a configuration pitfall we should avoid (e.g., formatter order, module settings)?

  4. Any recommended “golden” registration pattern for projects that need both System.Text.Json (for UI) and Newtonsoft (for specific APIs), to avoid casing drift?

References

Diagnostics available on request

  • Redacted HARs showing PascalCase vs. camelCase responses

  • Startup/Program snippets (formatter registrations)

  • Exact package lists for both projects

  • Network screenshots from the affected UIs

Thanks in advance for any confirmations, pointers, or official guidance.

#341284
Edited, Dec 16, 2025 13:20
Vote:
 

It appears as if you are spot on with your solutions already.

This is the most robust approach for Admin/Forms/Contacts UI stability already:

// Force System.Text.Json for UI-related controller assemblies
services.UseSystemTextJsonSerialization(typeof(EPiServer.Shell.ShellModule).Assembly);
services.UseSystemTextJsonSerialization(typeof(EPiServer.Cms.UI.Admin.Controllers.AdminController).Assembly);
// If applicable in your solution:
services.UseSystemTextJsonSerialization(typeof(EPiServer.Forms.UI.Controllers.SomeFormsUiController).Assembly);

That as well as the newtonsoft implementation already mentioned in your post

services.AddControllers()
  .AddNewtonsoftJson(o =>
  {
    o.SerializerSettings.ContractResolver =
      new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
  });

You also mentioned preferredUiJsonSerializerType formatting hygiene in your module.config's (if you have custom modules (or add-ons) shipping a module.config, ensure you’re not unintentionally forcing or "resolving" to Newtonsoft). What where your findings?

preferredUiJsonSerializerType="Resolve" can flip to Newtonsoft if any Newtonsoft converter is present. Prefer explicitly pinning to the built-in serializer for UI modules where possible (if this is relevant for your implementation).

It appears as if you found all the reasons why not to mix Json-frameworks and casings in .Net. 

#341291
Dec 17, 2025 8:44
Vote:
 

It appears as if you are spot on with your solutions already.

This is the most robust approach for Admin/Forms/Contacts UI stability already:

// Force System.Text.Json for UI-related controller assemblies
services.UseSystemTextJsonSerialization(typeof(EPiServer.Shell.ShellModule).Assembly);
services.UseSystemTextJsonSerialization(typeof(EPiServer.Cms.UI.Admin.Controllers.AdminController).Assembly);
// If applicable in your solution:
services.UseSystemTextJsonSerialization(typeof(EPiServer.Forms.UI.Controllers.SomeFormsUiController).Assembly);

That as well as the newtonsoft implementation already mentioned in your post

services.AddControllers()
  .AddNewtonsoftJson(o =>
  {
    o.SerializerSettings.ContractResolver =
      new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
  });

You also mentioned preferredUiJsonSerializerType formatting hygiene in your module.config's (if you have custom modules (or add-ons) shipping a module.config, ensure you’re not unintentionally forcing or "resolving" to Newtonsoft). What where your findings?

preferredUiJsonSerializerType="Resolve" can flip to Newtonsoft if any Newtonsoft converter is present. Prefer explicitly pinning to the built-in serializer for UI modules where possible (if this is relevant for your implementation).

It seems as if you found all the reasons why not to mix Json-frameworks and casings in .Net. 

#341292
Edited, Dec 17, 2025 8:44
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.