Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core Web API different JSON casing per controller

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?

like image 248
Zachary Wand Avatar asked Apr 19 '17 21:04

Zachary Wand


2 Answers

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);
    }        
}
like image 66
armache Avatar answered Oct 18 '22 18:10

armache


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;
}
like image 40
Danie Avatar answered Oct 18 '22 18:10

Danie