Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return camelCased JSON from Web API

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.

like image 859
beaudetious Avatar asked Oct 20 '14 20:10

beaudetious


People also ask

Can we return JSON from Web API?

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.

Which line of code can you use to format JSON data in camelCase?

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);

How do I return JSON in Web API net core?

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 .

How do you turn off or handle Camelcasing in JSON response in asp net core?

You have to change the DefaultContractResolver which uses camelCase by default. Just set the NamingStatergy as null . This should be done in the StartUp.


4 Answers

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.

like image 143
Omar.Alani Avatar answered Oct 20 '22 00:10

Omar.Alani


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.

like image 36
beaudetious Avatar answered Oct 19 '22 23:10

beaudetious


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);
}
like image 23
Jalal Avatar answered Oct 20 '22 01:10

Jalal


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");
        }
    }
like image 33
Jester Avatar answered Oct 19 '22 23:10

Jester