Structures and variables, preserving the original case
Preserving Key Case in CFML Structs / Variables
The Problem
You're building a REST API and returning a struct as JSON. Your code looks clean:
sct = {};
sct.firstName = "James";
sct.lastName = "Kirk";
serializeJSON( sct );
But the JSON output has uppercase keys:
{"FIRSTNAME":"James","LASTNAME":"Kirk"}
Your JavaScript frontend expects firstName, not FIRSTNAME. What's going on?
Why This Happens
In CFML, variable names are case-insensitive. To achieve this, Lucee converts all keys defined with dot notation to uppercase at compile time. This is the traditional CFML behaviour.
sct = {};
sct.firstName = "James"; // Would be stored as "FIRSTNAME"
sct["firstName"] = "Jamez"; // Would be still stored as "FIRSTNAME" (see note)
sct["lastName"] = "Kirk"; // Would be stored as "lastName" (bracket notation preserves case)
Note: in the above example, once a key is created, updating it will not change the key case, so sct["firstName"] does not change the original key case.
All variables in Lucee are stored in structs under the hood - variables, local, arguments, url, form - they all follow the same rules.
Solutions
Use Bracket Notation
Bracket notation always preserves case:
sct = {};
sct["firstName"] = "James";
sct["lastName"] = "Kirk";
Server-Wide Configuration
If you want dot notation to preserve case everywhere, Lucee has a compiler setting called dotNotationUpperCase.
true(default): Convert dot notation keys to uppercase (CFML standard)false: Preserve the original case
Configuring via Lucee Admin
- Open the Lucee Server or Web Admin
- Navigate to Settings → Language/Compiler
- Under Key Case, select "Preserve case"
Configuring via .CFConfig.json
{
"dotNotationUpperCase": false
}
Configuring via Environment Variable
LUCEE_PRESERVE_CASE=true
Or as a system property:
-Dlucee.preserve.case=true
Note: The environment variable uses preserve case logic (inverse of dotNotationUpperCase), so true means preserve case.
Per-Template Override
You can override the server setting for a specific template using <cfprocessingdirective>
<cfprocessingdirective preserveCase="true">
<cfscript>
sct = {};
sct.firstName = "James"; // Preserved as "firstName" in this template
</cfscript>
Checking the Current Setting
You can check what setting is active:
settings = getApplicationSettings();
writeOutput( settings.dotNotationUpperCase ); // true or false
Things to Consider
When set via the Lucee Admin / CFConfig.json, keep in mind this is server wide configuation.
If you're working with legacy code that assumes uppercase keys, switching to preserve case could break things. Test thoroughly.