5

We are trying to migrate an old API into our current .Net Core Web API. Our current API returns JSON using camelCasing, but our old API uses PascalCasing and we do not want to have to update the client.

Is there any way to specify which serialization strategy we want to use per controller, rather than global across the service?

3
  • Possible duplicate of asp.net core 1.0 web api use camelcase Commented Apr 20, 2017 at 6:36
  • I don't think so, I believe that is just asking for camelCase across the entire API, not per controller Commented Apr 20, 2017 at 14:19
  • We ended up adding [JsonProperty] tags to every attribute in our relevant models. Not the ideal solution (we have LOTS of models) but it is working for now. Commented Apr 25, 2017 at 14:27

2 Answers 2

8

Yes, you can achieve it by using attribute on your controller. See the sample below:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomJsonFormatter : ActionFilterAttribute
{
    private readonly string formatName = string.Empty;
    public CustomJsonFormatter(string _formatName)
    {
        formatName = _formatName;
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        if (context == null || context.Result == null)
        {
            return;
        }

        var settings = JsonSerializerSettingsProvider.CreateSerializerSettings();

        if (formatName == "camel")
        {
            settings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
        }            
        else
        {
            settings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
        }

        var formatter = new JsonOutputFormatter(settings, ArrayPool<Char>.Shared);

        (context.Result as Microsoft.AspNetCore.Mvc.OkObjectResult).Formatters.Add(formatter);
    }
}

and here is your controller:

[CustomJsonFormatter("camel")]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET: api/values
    [HttpGet]
    public IActionResult Get()
    {
        Car car = new Car { Color = "red", Make = "Nissan" };

        return Ok(car);
    }        
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @armache but I found my results were JsonResult not OKObjectResult so instead I had ((Microsoft.AspNetCore.Mvc.JsonResult)context.Result).SerializerSettings = settings; Also note that DefaultContractResolver isn't strictly PascalCase as the OP specified, it doesn't modify the case, normally C# will already be PascalCase and so it will stay PascalCase; it's probably what they wanted rather than what they asked for. I also removed the parameter from the attribute as it defaults to camel case and so only specify the attribute if I need PascalCase.
1

I have made an extension method for OkObjectResult to be able to choose where I do not want the camel case serialization behaviour. You can use it like this:

OkObjectResult(yourResponseObject).PreventCamelCase();

Here is the extension method:

public static OkObjectResult PreventCamelCase(this OkObjectResult response)
{
    var settings = JsonSerializerSettingsProvider.CreateSerializerSettings();
    settings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();

    var formatter = new JsonOutputFormatter(settings, ArrayPool<Char>.Shared);
    response.Formatters.Add(formatter);
    return response;
}

1 Comment

@GabrielLuca I also wonder that. I have been using this solution for half a year now in my 100+ API endpoints without any problems. Saved me probably at least one week of work not having to rewrite the clients after updating the API to .NET Core. This solution also let me choose which endpoints where I want this behaviour and not, so I can slowly transition my whole API to the new standards of .NET Core.

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.