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 t
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");
}
}
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);
}
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.
In Register method of WebApiConfig, add this
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
Full Code of WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}
Make sure you have installed latest version of Json.Net/Newtonsoft.Json Installed and your API Action Method returns data in following way:
[HttpGet]
public HttpResponseMessage List()
{
try
{
var result = /*write code to fetch your result*/;
return Request.CreateResponse(HttpStatusCode.OK, result);
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
}
}
Try this also.
[AllowAnonymous]
[HttpGet()]
public HttpResponseMessage GetAllItems(int moduleId)
{
HttpConfiguration config = new HttpConfiguration();
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;
try
{
List<ItemInfo> itemList = GetItemsFromDatabase(moduleId);
return Request.CreateResponse(HttpStatusCode.OK, itemList, config);
}
catch (System.Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
}
}