My Custom Action Filter Attribute to convert a JSON response of MVC core webApi from "camelCase" to "pascalCase" is not working.
Tried using:
services.AddMvc()
.AddJsonOptions(options =>
options.SerializerSettings.ContractResolver = new DefaultContractResolver());
However, this kind of global setting changes all response to Pascal case. I want to change only a limited API response to Pascal case.
Custom ActionFilterAttribute
:
public class CancelCamelCaseResolverConfigurationAttribute : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext context)
{
base.OnResultExecuted(context);
var objectResult = context.Result as ObjectResult;
if (objectResult != null)
{
objectResult.Formatters.Clear();
objectResult.Formatters.Add(new JsonOutputFormatter(
new JsonSerializerSettings()
{
Formatting = Formatting.None,
ContractResolver = new DefaultContractResolver()
}, ArrayPool<char>.Shared));
}
}
}
And use in the webApi controller:
[CancelCamelCaseResolverConfiguration]
public class FrmMainSearchController : AtlasApiController<FrmMainSearchController>
{
/*Api*/
}
Expected result:
searchCriteria = [{Key: "xx", Value: "yy"}]
Actual result:
searchCriteria = [{key: "xx", value: "yy"}]
You're almost there: You need override the OnActionExecuted()
method instead of the OnResultExecuted()
.
It's too late to change the formatters when the OnResultExecuted()
filter method is invoked.
Override the OnResultExecuted
method so that the formatter is changed before the result execution:
public override void OnResultExecuted(ResultExecutedContext context)public override void OnActionExecuted(ActionExecutedContext context) { ... }
As a side note, you didn't check for type JsonResult
. To make it work with Json()
or JsonResult()
, you need check the result type dynamically:
public class CancelCamelCaseResolverConfigurationAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
switch(context.Result){
case JsonResult j:
var result = new ObjectResult(j.Value);
context.Result = result;
ChangeFormatting(result);
break;
case ObjectResult o:
ChangeFormatting(o);
break;
default:
return;
}
}
private void ChangeFormatting(ObjectResult result){
if (result == null){ return; }
result.Formatters.Clear();
result.Formatters.Add(new JsonOutputFormatter(
new JsonSerializerSettings()
{
Formatting = Formatting.None,
ContractResolver = new DefaultContractResolver()
}, ArrayPool<char>.Shared)
);
}
}