Skip to content

Instantly share code, notes, and snippets.

@AndyButland
Created May 30, 2023 15:46
Show Gist options
  • Save AndyButland/d0dc71ba2312303c95624fdff8db74d5 to your computer and use it in GitHub Desktop.
Save AndyButland/d0dc71ba2312303c95624fdff8db74d5 to your computer and use it in GitHub Desktop.
public class MyApiControllerAttribute : ActionFilterAttribute
{
/// <inheritdoc/>
public override void OnActionExecuted(ActionExecutedContext ctx)
{
if (ctx.Result is ObjectResult objectResult)
{
// Create options to match the CMS delivery API, along with any customizations we want for Forms.
var options = new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
// Output properties in alphabetical order.
// Hat-tip: https://stackoverflow.com/a/72593993
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers = { AlphabetizeProperties() },
},
};
options.Converters.Add(new JsonStringEnumConverter());
objectResult.Formatters.Add(new SystemTextJsonOutputFormatter(options));
}
}
private static Action<JsonTypeInfo> AlphabetizeProperties(Type type) =>
typeInfo =>
{
if (typeInfo.Kind != JsonTypeInfoKind.Object || !type.IsAssignableFrom(typeInfo.Type))
{
return;
}
AlphabetizeProperties()(typeInfo);
};
private static Action<JsonTypeInfo> AlphabetizeProperties() =>
static typeInfo =>
{
if (typeInfo.Kind != JsonTypeInfoKind.Object)
{
return;
}
var properties = typeInfo.Properties.OrderBy(p => p.Name, StringComparer.Ordinal).ToList();
typeInfo.Properties.Clear();
for (int i = 0; i < properties.Count; i++)
{
properties[i].Order = i;
typeInfo.Properties.Add(properties[i]);
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment