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

KennyG
Jun 2, 2025
  1020
(0 votes)

Follow-Up: Fixing JSON Casing in Optimizely CMS Export Data

*Note: This issue seems to be resolved with EPiServer.CMS Version 12.33.1.

A Targeted Action Filter to Enforce CamelCase

In my previous blog post, I discussed an issue we were having with JSON formatting in Optimizely CMS exports after updating NuGet packages. Specifically, the /EPiServer/EPiServer.Cms.UI.Admin/ExportData/GetExportStatus endpoint returned PascalCase JSON property names, breaking other parts of our site where the frontend expected camelCase.

That led to UI failures—most notably, a never-ending loading spinner. To address this without affecting global JSON settings, I implemented an action filter that ensures camelCase formatting for this specific route. Here’s how it works.

Recap: Why JSON Formatting Matters

Many JavaScript frameworks (like React and Angular) expect JSON property names in camelCase. When a response unexpectedly comes in PascalCase, bindings can break, leading to missing data or even complete UI failures.

Instead of globally modifying JSON settings—which might have unintended consequences across the CMS—the best approach is a targeted fix that applies only to the problematic endpoint.

The Solution: CamelCase JSON for Export Status

This ASP.NET Core action filter ensures JSON responses from /EPiServer/EPiServer.Cms.UI.Admin/ExportData/GetExportStatus are always camelCase:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Formatters;
using System.Text.Json;
using System.Linq;
using System.Text.Json.Serialization.Metadata;

namespace Website.API.Filters
{
    /// <summary>
    /// Action filter to enforce camelCase JSON for /EPiServer/EPiServer.Cms.UI.Admin/ExportData/GetExportStatus responses.
    /// </summary>
    public class CamelCaseJsonForExportStatusFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            // No action needed before execution
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            // Only apply to the specific route
            var path = context.HttpContext.Request.Path.Value;
            if (!string.Equals(path, "/EPiServer/EPiServer.Cms.UI.Admin/ExportData/GetExportStatus",
                    StringComparison.OrdinalIgnoreCase))
                return;

            if (context.Result is ObjectResult objectResult)
            {
                // Find the SystemTextJsonOutputFormatter and update its options
                var jsonFormatter = objectResult.Formatters
                    .OfType<SystemTextJsonOutputFormatter>()
                    .FirstOrDefault();

                if (jsonFormatter != null)
                {
                    // Update the naming policy to camelCase
                    jsonFormatter.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                }
                else
                {
                    objectResult.Formatters.Add(new SystemTextJsonOutputFormatter(
                        new JsonSerializerOptions
                        {
                            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                            WriteIndented = false,
                            TypeInfoResolver = new DefaultJsonTypeInfoResolver()
                        }
                    ));
                }
            }
        }
    }
}

How to Plug It In

Add the following to Startup.cs to register the filter globally (since it self-filters by route):

services.AddControllersWithViews(options =>
{
    options.Filters.Add<CamelCaseJsonForExportStatusFilter>();
});

The filter only runs logic when the request is for /ExportData/GetExportStatus, so it’s safe to register app-wide.

How It Works

  1. Intercepting the Response
    • The filter implements IActionFilter, modifying responses after an action executes.
    • OnActionExecuting remains empty since no changes are needed before execution.
    • OnActionExecuted checks if the request path matches the export status endpoint.
  2. Applying JSON Formatting
  • If the response is an ObjectResult, it searches for an existing SystemTextJsonOutputFormatter.
  • If found, it updates its SerializerOptions.PropertyNamingPolicy to JsonNamingPolicy.CamelCase.
  • If no formatter exists, it adds a new one with the correct settings.

Why This Approach?

  • Scoped Fix – Only affects /ExportData/GetExportStatus, leaving other JSON responses untouched.
  • Minimal Overhead – Modifies existing formatters when possible, optimizing performance.
  • Future-Proofing – Ensures a formatter exists even if Optimizely CMS updates its behavior later.

Conclusion

This targeted action filter prevents unexpected JSON formatting issues in Optimizely CMS. By enforcing camelCase only for the export status response, it eliminates UI failures while avoiding unnecessary changes to global settings.

Let me know if you have alternative approaches or thoughts—drop them in the comments. 

Jun 02, 2025

Comments

Please login to comment.
Latest blogs
A day in the life of an Optimizely OMVP: Learning Optimizely Just Got Easier: Introducing the Optimizely Learning Centre

On the back of my last post about the Opti Graph Learning Centre, I am now happy to announce a revamped interactive learning platform that makes...

Graham Carr | Jan 31, 2026

Scheduled job for deleting content types and all related content

In my previous blog post which was about getting an overview of your sites content https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/sche...

Per Nergård (MVP) | Jan 30, 2026

Working With Applications in Optimizely CMS 13

💡 Note:  The following content has been written based on Optimizely CMS 13 Preview 2 and may not accurately reflect the final release version. As...

Mark Stott | Jan 30, 2026

Experimentation at Speed Using Optimizely Opal and Web Experimentation

If you are working in experimentation, you will know that speed matters. The quicker you can go from idea to implementation, the faster you can...

Minesh Shah (Netcel) | Jan 30, 2026