I need specific JSON settings per controller in my ASP.NET MVC 6 webApi. I found this sample that works (I hope !) for MVC 5 : Force CamelCase on ASP.NET WebAPI Per Controller
using System;
using System.Linq;
using System.Web.Http.Controllers;
using System.Net.Http.Formatting;
using Newtonsoft.Json.Serialization;
public class CamelCaseControllerConfigAttribute : Attribute, IControllerConfiguration
{
public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
{
var formatter = controllerSettings.Formatters.OfType<JsonMediaTypeFormatter>().Single();
controllerSettings.Formatters.Remove(formatter);
formatter = new JsonMediaTypeFormatter
{
SerializerSettings = {ContractResolver = new CamelCasePropertyNamesContractResolver()}
};
controllerSettings.Formatters.Add(formatter);
}
}
This class works fine :
using System;
using System.Linq;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNet.Mvc.Filters;
using Newtonsoft.Json;
using Microsoft.AspNet.Mvc.Formatters;
namespace Teedl.Web.Infrastructure
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class MobileControllerConfiguratorAttribute : Attribute, IResourceFilter
{
private readonly JsonSerializerSettings serializerSettings;
public MobileControllerConfiguratorAttribute()
{
serializerSettings = new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple,
Binder = new TypeNameSerializationBinder("Teedl.Model.Mobile.{0}, Teedl.Model.ClientMobile")
};
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
var mobileInputFormatter = new JsonInputFormatter(serializerSettings);
var inputFormatter = context.InputFormatters.FirstOrDefault(frmtr => frmtr is JsonInputFormatter);
if (inputFormatter != null)
{
context.InputFormatters.Remove(inputFormatter);
}
context.InputFormatters.Add(mobileInputFormatter);
var mobileOutputFormatter = new JsonOutputFormatter(serializerSettings);
var outputFormatter = context.OutputFormatters.FirstOrDefault(frmtr => frmtr is JsonOutputFormatter);
if (outputFormatter != null)
{
context.OutputFormatters.Remove(outputFormatter);
}
context.OutputFormatters.Add(mobileOutputFormatter);
}
}
}
Use :
[Route("api/mobile/businessrequest")]
[Authorize]
[MobileControllerConfigurator]
public class MobileBusinessRequestController : BaseController
{
You can use a return type of JsonResult on your controller action methods. In my case, I needed specific actions to return Pascal Case for certain legacy scenarios. The JsonResult object allows you to pass an optional parameter as the JsonSerializerSettings.
public JsonResult Get(string id)
{
var data = _service.getData(id);
return Json(data, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver()
});
}
To have more consistent controller method signatures I ended up creating an extension method:
public static JsonResult ToPascalCase(this Controller controller, object model)
{
return controller.Json(model, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver()
});
}
Now I can simply call the extension method inside my controller like below:
public IActionResult Get(string id)
{
var data = _service.getData(id);
return this.ToPascalCase(data);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With