3

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"}]
0

1 Answer 1

4

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.

How to fix:

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)
        );
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.