I'm trying to return camel cased JSON from an ASP.Net Web API 2 controller. I created a new web application with just the ASP.Net MVC and Web API bits in it. I hijacked the ValuesController like so:
public class ValuesController : ApiController
{
public class Thing
{
public int Id { get; set; }
public string FirstName { get; set; }
public string ISBN { get; set; }
public DateTime ReleaseDate { get; set; }
public string[] Tags { get; set; }
}
// GET api/values
public IHttpActionResult Get()
{
var thing = new Thing
{
Id = 123,
FirstName = "Brian",
ISBN = "ABC213",
ReleaseDate = DateTime.Now,
Tags = new string[] { "A", "B", "C", "D"}
};
return Json(thing);
}
}
Running this in IE, I get the following results:
{"Id":123,"FirstName":"Brian","ISBN":"ABC213","ReleaseDate":"2014-10-20T16:26:33.6810554-04:00","Tags":["A","B","C","D"]}
Following K. Scott Allen's post on the subject, I added the following to the Register method in the WebApiConfig.cs file:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
However, I still get the same, capitilization in my results. Is there something I'm missing? I've tried a few other approaches but nothing works yet.
By default, Web API produces XML but if there is need for JSON, given syntax will do it. Open WebApiConfig. cs file in solution and add mentioned line in it as shown in example.
If you want JsonSerializer class to use camel casing you can do the following: var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy. CamelCase }; string json = JsonSerializer. Serialize(empList, options); return Ok(json);
To return data in a specific format from a controller that inherits from the Controller base class, use the built-in helper method Json to return JSON and Content for plain text. Your action method should return either the specific result type (for instance, JsonResult ) or IActionResult .
You have to change the DefaultContractResolver which uses camelCase by default. Just set the NamingStatergy as null . This should be done in the StartUp.
In your WebApiConfig.cs make sure to add those two lines
// Serialize with camelCase formatter for JSON.
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
make sure that you installed Newtonsoft library.
Hope that helps.
Looks like the main issue was that I was using the JsonResult shortcut Json() action result method:
public IHttpActionResult Get([FromUri] string domain, [FromUri] string username)
{
var authInfo = BLL.GetAuthenticationInfo(domain, username);
return Json(authInfo);
}
It apparently had full control of formatting the results. If I switch to returning HttpResponseMessage then it works as expected:
public HttpResponseMessage Get([FromUri] string domain, [FromUri] string username)
{
var authInfo = BLL.GetAuthenticationInfo(domain, username);
return Request.CreateResponse(HttpStatusCode.OK, authInfo);
}
I did end up using the block of code in the WebApiConfig file as Omar.Alani suggested (opposed to the much lengthier code I had in my OP). But the real culprit was the JsonResult action method. I hope this helps someone else out.
You need to use OK()
instead of Json()
in your action methods.
// GET api/values
public IHttpActionResult Get()
{
var thing = new Thing
{
Id = 123,
FirstName = "Brian",
ISBN = "ABC213",
ReleaseDate = DateTime.Now,
Tags = new string[] { "A", "B", "C", "D"}
};
// Use 'Ok()' instead of 'Json()'
return Ok(thing);
}
I was using Owin and DI (AutoFac in my case) so that throws another wrench into the works. My Startup.cs contains:
var apiconfig = new HttpConfiguration
{
DependencyResolver = new AutofacWebApiDependencyResolver(container)
};
WebApiConfig.Register(apiconfig);
Then in my WebApiConfig.cs I have:
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
// Setup json.Net for pretty output, easy human reading AND this formatter
// does that ONLY for browsers - best of both worlds: useful AND efficient/performant!
config.Formatters.Clear();
config.Formatters.Add(new BrowserJsonFormatter());
}
public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
// Since most browser defaults do not include an "accept type" specifying json, this provides a work around
// Default to json over XML - any app that wants XML can ask specifically for it ;)
public BrowserJsonFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
SerializerSettings.Formatting = Formatting.Indented;
SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// Convert all dates to UTC
SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
}
// Change the return type to json, as most browsers will format correctly with type as text/html
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}
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