I would like to return camel-cased JSON data using Web API. I inherited a mess of a project that uses whatever casing the previous programmer felt like using at the moment (seriously! all caps, lowercase, pascal-casing & camel-casing - take your pick!), so I can't use the trick of putting this in the WebApiConfig.cs file because it will break the existing API calls:
// Enforce camel-casing for the JSON objects being returned from API calls.
config.Formatters.OfType<JsonMediaTypeFormatter>().First().SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
So I'm using a custom class that uses the JSON.Net serializer. Here is the code:
using System.Web.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
public class JsonNetApiController : ApiController
{
public string SerializeToJson(object objectToSerialize)
{
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
if (objectToSerialize != null)
{
return JsonConvert.SerializeObject(objectToSerialize, Formatting.None, settings);
}
return string.Empty;
}
}
The problem is that the raw data returned looks like this:
"[{\"average\":54,\"group\":\"P\",\"id\":1,\"name\":\"Accounting\"}]"
As you can see, the backslashes mess things up. Here is how I'm calling using the custom class:
public class Test
{
public double Average { get; set; }
public string Group { get; set; }
public int Id { get; set; }
public string Name { get; set; }
}
public class SomeController : JsonNetApiController
{
public HttpResponseMessage Get()
var responseMessage = new List<Test>
{
new Test
{
Id = 1,
Name = "Accounting",
Average = 54,
Group = "P",
}
};
return Request.CreateResponse(HttpStatusCode.OK, SerializeToJson(responseMessage), JsonMediaTypeFormatter.DefaultMediaType);
}
What can I do differently to get rid of the backslashes? Is there an alternative way to enforcing camel-casing?
Thanks to all the references to other Stackoverflow pages, I'm going to post three solutions so anyone else having a similar issue can take their pick of the code. The first code example is one that I created after looking at what other people were doing. The last two are from other Stackoverflow users. I hope this helps someone else!
// Solution #1 - This is my solution. It updates the JsonMediaTypeFormatter whenever a response is sent to the API call.
// If you ever need to keep the controller methods untouched, this could be a solution for you.
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;
using Newtonsoft.Json.Serialization;
public class CamelCasedApiController : ApiController
{
public HttpResponseMessage CreateResponse(object responseMessageContent)
{
try
{
var httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK, responseMessageContent, JsonMediaTypeFormatter.DefaultMediaType);
var objectContent = httpResponseMessage.Content as ObjectContent;
if (objectContent != null)
{
var jsonMediaTypeFormatter = new JsonMediaTypeFormatter
{
SerializerSettings =
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
}
};
httpResponseMessage.Content = new ObjectContent(objectContent.ObjectType, objectContent.Value, jsonMediaTypeFormatter);
}
return httpResponseMessage;
}
catch (Exception exception)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, exception.Message);
}
}
}
The second solution uses an attribute to decorate the API controller method.
// http://stackoverflow.com/questions/14528779/use-camel-case-serialization-only-for-specific-actions
// This code allows the controller method to be decorated to use camel-casing. If you can modify the controller methods, use this approach.
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http.Filters;
using Newtonsoft.Json.Serialization;
public class CamelCasedApiMethodAttribute : ActionFilterAttribute
{
private static JsonMediaTypeFormatter _camelCasingFormatter = new JsonMediaTypeFormatter();
static CamelCasedApiMethodAttribute()
{
_camelCasingFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
public override void OnActionExecuted(HttpActionExecutedContext httpActionExecutedContext)
{
var objectContent = httpActionExecutedContext.Response.Content as ObjectContent;
if (objectContent != null)
{
if (objectContent.Formatter is JsonMediaTypeFormatter)
{
httpActionExecutedContext.Response.Content = new ObjectContent(objectContent.ObjectType, objectContent.Value, _camelCasingFormatter);
}
}
}
}
// Here is an example of how to use it.
[CamelCasedApiMethod]
public HttpResponseMessage Get()
{
...
}
The last solution uses an attribute to decorate the entire API controller.
// http://stackoverflow.com/questions/19956838/force-camalcase-on-asp-net-webapi-per-controller
// This code allows the entire controller to be decorated to use camel-casing. If you can modify the entire controller, use this approach.
using System;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http.Controllers;
using Newtonsoft.Json.Serialization;
public class CamelCasedApiControllerAttribute : Attribute, IControllerConfiguration
{
public void Initialize(HttpControllerSettings httpControllerSettings, HttpControllerDescriptor httpControllerDescriptor)
{
var jsonMediaTypeFormatter = httpControllerSettings.Formatters.OfType<JsonMediaTypeFormatter>().Single();
httpControllerSettings.Formatters.Remove(jsonMediaTypeFormatter);
jsonMediaTypeFormatter = new JsonMediaTypeFormatter
{
SerializerSettings =
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
}
};
httpControllerSettings.Formatters.Add(jsonMediaTypeFormatter);
}
}
// Here is an example of how to use it.
[CamelCasedApiController]
public class SomeController : ApiController
{
...
}
If you want to set it globally you can just remove the current Json formatter from the HttpConfiguration and replace it with your own.
public static void Register(HttpConfiguration config)
{
config.Formatters.Remove(config.Formatters.JsonFormatter);
var serializer = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
var formatter = new JsonMediaTypeFormatter { Indent = true, SerializerSettings = serializer };
config.Formatters.Add(formatter);
}
Comment on https://stackoverflow.com/a/26506573/887092 works for some cases but not others
var jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
This way works in other cases
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
So, cover all bases with:
private void ConfigureWebApi(HttpConfiguration config)
{
//..
foreach (var jsonFormatter in config.Formatters.OfType<JsonMediaTypeFormatter>())
{
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
var singlejsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
singlejsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
Related
I am using a middleware to sanitize asp.net endpoints using HtmlSanitizer as explained here. But its not working for file uploads. So I am trying to use a custom attribute called XssSanitizeIgnore as explained in the discussions section.
I create XssSanitizeIgnore attribute inside My controller as follows,
namespace CarPortal.ReportingServiceApi.Controllers.APIControllers
{
[Route("api/[controller]")]
[ApiController]
public class AutoReportController : BaseController
{
private readonly IAutoReportService _autoReportService;
public AutoReportController(IAutoReportService autoReportService) : base()
{
_autoReportService = autoReportService;
}
[HttpPost]
[XssSanitizeIgnore]
[Route("ProcessUploadedFile")]
public async Task<string> ProcessUploadedFile([FromForm] object formData)
{
return await _autoReportService.ProcessUploadedFile((IFormFile)formData);
}
}
}
[System.AttributeUsage(System.AttributeTargets.All)]
public class XssSanitizeIgnore: Attribute
{
}
but I am not sure how can I use it inside the middleware
// enable buffering so that the request can be read by the model binders next
httpContext.Request.EnableBuffering();
// leaveOpen: true to leave the stream open after disposing, so it can be read by the model binders
using (var streamReader = new StreamReader(httpContext.Request.Body, Encoding.UTF8, leaveOpen: true))
{
var raw = await streamReader.ReadToEndAsync();
var sanitiser = new HtmlSanitizer();
var sanitised = sanitiser.Sanitize(raw);
System.Attribute[] attrs = System.Attribute.GetCustomAttributes(typeof(AutoReportController));
//ignore if XssSanitizeIgnore
if (raw != sanitised)
{
throw new BadRequestException("XSS injection detected from middleware.");
}
}
// rewind the stream for the next middleware
httpContext.Request.Body.Seek(0, SeekOrigin.Begin);
await _next.Invoke(httpContext);
You can use this snippet code to check if this endpoint has an attribute.
var endpoint = httpContext.GetEndpoint();
var myCustomAttribute = endpoint?.Metadata?.GetMetadata<MyCustomAttribute>();
if (myCustomAttribute is not null)
{
// ToDo: do someting
}
and if possible use this attribute more than once so you can use this instead.
var endpoint = httpContext.GetEndpoint();
var myCustomAttributes = endpoint?.Metadata?.GetOrderedMetadata<MyCustomAttribute>();
if (myCustomAttributes != null && myCustomAttributes.Any())
{
// ToDo: do someting
}
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);
}
I need to make a simple webapi call to post method with string argument.
Below is the code I'm trying, but when the breakpoint is hit on the webapi method, the received value is null.
StringContent stringContent = new System.Net.Http.StringContent("{ \"firstName\": \"John\" }", System.Text.Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(url.ToString(), stringContent);
and server side code:
// POST api/values
[HttpPost]
public void Post([FromBody]string value)
{
}
please help...
If you want to send a json to your Web API, the best option is to use a model binding feature, and use a Class, instead a string.
Create a model
public class MyModel
{
[JsonProperty("firstName")]
public string FirstName { get; set; }
}
If you wont use the JsonProperty attribute, you can write property in lower case camel, like this
public class MyModel
{
public string firstName { get; set; }
}
Then change you action, change de parameter type to MyModel
[HttpPost]
public void Post([FromBody]MyModel value)
{
//value.FirstName
}
You can create C# classes automatically using Visual Studio, look this answer here Deserialize JSON into Object C#
I made this following test code
Web API Controller and View Model
using System.Web.Http;
using Newtonsoft.Json;
namespace WebApplication3.Controllers
{
public class ValuesController : ApiController
{
[HttpPost]
public string Post([FromBody]MyModel value)
{
return value.FirstName.ToUpper();
}
}
public class MyModel
{
[JsonProperty("firstName")]
public string FirstName { get; set; }
}
}
Console client application
using System;
using System.Net.Http;
namespace Temp
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Enter to continue");
Console.ReadLine();
DoIt();
Console.ReadLine();
}
private static async void DoIt()
{
using (var stringContent = new StringContent("{ \"firstName\": \"John\" }", System.Text.Encoding.UTF8, "application/json"))
using (var client = new HttpClient())
{
try
{
var response = await client.PostAsync("http://localhost:52042/api/values", stringContent);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(ex.Message);
Console.ResetColor();
}
}
}
}
}
Output
Enter to continue
"JOHN"
Alternative answer: You can leave your input parameter as string
[HttpPost]
public void Post([FromBody]string value)
{
}
, and call it with the C# httpClient as follows:
var kvpList = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("", "yo! r u dtf?")
};
FormUrlEncodedContent rqstBody = new FormUrlEncodedContent(kvpList);
string baseUrl = "http://localhost:60123"; //or "http://SERVERNAME/AppName"
string C_URL_API = baseUrl + "/api/values";
using (var httpClient = new HttpClient())
{
try
{
HttpResponseMessage resp = await httpClient.PostAsync(C_URL_API, rqstBody); //rqstBody is HttpContent
if (resp != null && resp.Content != null) {
var result = await resp.Content.ReadAsStringAsync();
//do whatevs with result
} else
//nothing returned.
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(ex.Message);
Console.ResetColor();
}
}
For the record I tried the above and could not get it working!
I couldn't get it working because my API was in a separate project. Which is fine right? no, I was doing Dependency Injection into the controller while using the Startup class against the Base project.
You can resolve this by using the WebAPI's config and configuring Dependency Injection there with Unity. The below code works for me:
WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
RegisterUnity();
}
private static void RegisterUnity()
{
var container = new UnityContainer();
container.RegisterType<IIdentityRespository, IdentityRespository>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
I hope it helps others :-)
This is my Web API and it works fine, I mean when i enter this URL on my browser:
http://localhost:18207/api/values/GetMyClass
I retrieve this result:
<MyClass>
<A>a</A>
<b>b</b>
</MyClass>
My codes:
public class MyClass
{
public MyClass()
{
this.A = "a";
this.b = "b";
}
public string A { get; set; }
public string b { get; set; }
}
public class ValuesController : ApiController
{
public MyClass GetMyClass()
{
return new MyClass();
}
}
I have another console application to use my Web API and want to know,
How can i have a complex or object type of MyClass?
Codes on my Console are below but it returns string type
static void Main(string[] args)
{
var cts = new CancellationTokenSource();
MainAsync(args, cts.Token).Wait();
}
static async Task MainAsync(string[] args, CancellationToken token)
{
string baseAddress = "http://localhost:18207/api/values/GetMyClass";
using (var httpClient = new HttpClient())
{
string response = await httpClient.GetStringAsync(baseAddress);
}
}
Your response is probably coming to your console application as JSON (the reason your browser receives it as XML is because of different Accept headers, you can learn about that if you look at Content Negotiation). So what you need to do is parse the JSON and have it deserialize it into your object. There's quite a few libraries that can do that for you.
First make sure that your MyClass is defined in a Class Library project that both your Web API project and your Console project are referencing. This allows us to reuse the class definition without needing to have a separate copy in both projects.
Next, you need a JSON parsing library. There's one built into .NET, but there's a 3rd party one called Json.NET that is the gold standard. My answer will use that one since I'm more familiar with it. Install the Newtonsoft.Json package into your console app.
Then, change your console app as follows:
using Newtonsoft.Json; // at the top of your file
static void Main(string[] args)
{
var cts = new CancellationTokenSource();
MainAsync(args, cts.Token).Wait();
}
static async Task MainAsync(string[] args, CancellationToken token)
{
string baseAddress = "http://localhost:18207/api/values/GetMyClass";
using (var httpClient = new HttpClient())
{
string json = await httpClient.GetStringAsync(baseAddress);
MyClass instance = JsonConvert.DeserializeObject<MyClass>(json);
}
}
The JsonConvert class handles serializing and deserializing the JSON. When deserializing, we just tell is which class to deserialize to and it will attempt to convert the JSON to an instance of that class and return it.
You can use method "GetAsync" which will return object of class "HttpResponseMessage" and then you can call "ReadAsAsync" on Content property.
Please see below code:
public class MyClass
{
public MyClass()
{
this.A = "a";
this.b = "b";
}
public string A { get; set; }
public string b { get; set; }
}
static void Main(string[] args)
{
var cts = new CancellationTokenSource();
MainAsync(args, cts.Token).Wait();
}
static async Task MainAsync(string[] args, CancellationToken token)
{
string baseAddress = "http://localhost:18207/api/values/GetMyClass";
using (var httpClient = new HttpClient())
{
HttpResponseMessage response = await httpClient.GetAsync(baseAddress);
response.EnsureSuccessStatusCode();
MyClass result = await response.Content.ReadAsAsync< MyClass>();
}
}
Here is the full solution end-to-end. We are hosting a Web Api that returns MyClass and then we are calling the API and getting data formatted as XML through a console application.
First, we have MyClass annotated as a DataContract:
[DataContract]
public class MyClass
{
public MyClass()
{
this.A = "a";
this.b = "b";
}
[DataMember]
public string A { get; set; }
[DataMember]
public string b { get; set; }
}
The MyClass Web API:
[AllowAnonymous]
public class MyClassController : ApiController
{
public MyClass Get()
{
return new MyClass();
}
}
and a Console app that uses HttpWebRequest to call the Web Api.
Here's that code (the bottom half is from my original post):
static void Main(string[] args)
{
// this is my Web API Endpoint
var req = (HttpWebRequest)WebRequest.Create("http://localhost:17512/api/MyClass");
// default is JSON, but you can request XML
req.Accept = "application/xml";
req.ContentType = "application/xml";
var resp = req.GetResponse();
var sr = new StreamReader(resp.GetResponseStream());
// read the response stream as Text.
var xml = sr.ReadToEnd();
var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));
// Deserialize
var ser = new XmlSerializer(typeof(MyClass));
var instance = (MyClass)ser.Deserialize(ms);
Console.WriteLine(instance.A);
Console.WriteLine(instance.b);
var final = Console.ReadLine();
}
NOTE: You'll need to figure out if you want to share a reference to MyClass between the two assemblies or if you just want to have a copy of the code file in each project.
You could just remove XML Formatter inside your WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Removing XML
config.Formatters.Remove(config.Formatters.XmlFormatter);
// Allows us to map routes using [Route()] and [RoutePrefix()]
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Then in your controller you would return just like in your example:
public class ValuesController : ApiController
{
public MyClass GetMyClass()
{
return new MyClass();
}
}
UPDATE 1: I did my answer become more consistent with the question
When making a Request from a Console Application, you could use RestSharp.
var client = new RestClient("http://localhost:18207/");
var request = new RestRequest("api/values/GetMyClass", Method.GET);
var response = client.Execute<MyClass>(request);
if(response.StatusCode == HttpStatusCode.OK)
var responseData = response.Data;
When you execute client.Execute<MyClass>(request) it will deserialize the response into an object of that class. If field names match it should work.
I have an web api controller
using sport.BLL.Abstract;
using sport.BLL.Concrete;
using sport.DAL.Entities;
using sport.webApi.Models;
using AutoMapper;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web;
using System.Web.WebPages.Html;
namespace sport.webApi.Controllers
{
public class AccountManageController : ApiController
{
[HttpPost]
public System.Web.Mvc.ActionResult CreateAccount(CollaborateurModel item)
{
var user = new ApplicationUser { UserName = item.Username, Email = item.Email };
var result = UserManager.CreateAsync(user, item.Password);
if (result.Result.Succeeded)
{
var currentUser = UserManager.FindByName(item.Username);
var roleresult = UserManager.AddToRole(currentUser.Id, item.Role);
ajt_collaborator entity = Mapper.Map<CollaborateurModel, ajt_collaborator>(item);
entity.id_user_fk = currentUser.Id;
entity.is_deleted = false;
repo.CreateCollaborator(entity);
var response = new { Success = true };
return Json(response);
}
else
{
var errorResponse = new { Success = false, ErrorMessage = "error" };
return Json(errorResponse);
}
}
}
}
I got an error in this line :
return Json(response);
the Json Method is not recognized!!! when I googled about that I get this link which indicates that Json method is included in System.Web.Mvc. Even I try to import this namespace I get the same error?
So is the reason of this error?
How can I fix it?
The problem is that you are inheriting from ApiController but Json is a member of System.Web.Mvc.Controller.
Try using JsonResult:
return new JsonResult { data = yourData; }
You can set any object to a data as it will be serialized to a JSON.
For instance, if you need to return only a result of operation, you can use it this way:
return new JsonResult { data = true; } // or false
However, it is a good practice to describe a result class and return objects.
How can I fix it?
The reason is in the fact that you aren't inheriting from Controller but from ApiController, where the former has Json(object o) as a method in it's base class, but that doesn't actually matter, as there is a fundamental problem with your approach.
ApiController which is used with WebAPI isn't meant to return an ActionResult, which is a concept that belongs to MVC. Instead, you simply return your POCO and let the WebAPI framework handle serialization for you:
public object CreateAccount(CollaborateurModel item)
{
// Do stuff:
if (result.Result.Succeeded)
{
return new { Success = true }
}
else
{
return new { Success = false, ErrorMessage = "error" };
}
}
You can set your formatter configuration in your Global.asax.cs file, and tell it exactly which ones to use (in your case, you'll want the JsonMediaTypeFormatter).