0

I have an api controller action that takes a JObject as a

public class ThemeController : ApiController
{
    [HttpGet]
    public String Get(String siteName, JObject lessVariables)
    {

and an ajax call

$.ajax({
    url: '/api/Theme/Get',
    data: { lessVariables: JSON.stringify({'brand-primary': '#222222','brand-success': '#222222','brand-danger': '#222222','brand-info': '#222222','btn-primary-color': '#222222'}), siteName: "UnivOfUtah" }
    });

When I look at HttpContext.Current.Request.Params["lessVariables"] it gives the correct string of json, but lessVariables is an empty JObject. Is there something else I have to do to setup Json.Net for this?

I've also tried it on a regular controller action

I have a controller action that takes a JObject as a

public class ThemeController : Controller
{
    [HttpPost]
    public String Post(String siteName, JObject lessVariables)
    {

and an ajax call

$.ajax({
    url: '/Theme/Post',
    data: { lessVariables: JSON.stringify({'brand-primary': '#222222','brand-success': '#222222','brand-danger': '#222222','brand-info': '#222222','btn-primary-color': '#222222'}), siteName: "UnivOfUtah" }
    });

same result

DrSammyD
  • 880
  • 12
  • 32

1 Answers1

3

The problem is that lessVariables is now a String. The whole structure probably looks like:

{
    "lessVariables": "{'brand-primary': '#222222','brand-success': '#222222','brand-danger': '#222222','brand-info': '#222222','btn-primary-color': '#222222'}",
    "siteName": "UnivOfUtah"
}

This is why you can see the correct string in the Params, but the framework is not able to convert it to JObject without knowing it is Json. When you Stringify the root object of a request, WebApi is smart enough to take it as Json as a whole, but you stringified a value inside so it has no idea it should be handled as json.

To fix it, you can either do custom binding with a model binder or custom action, or simply change your method to:

[HttpGet]
public String Get(String siteName, String lessVariables)
{
    JObject jo = JObject.Parse(lessVariables);

Update:

To make the issue clearer, this is parsed fine by WebApi, but lessVariables is still a string:

[HttpGet]
public String Get(JObject rootObject)
{
    // you now have rootObject which has a "siteName" and "lessVariables" parameter
    var siteName = rootObject.GetValue("siteName");
    var lessVariables = rootObject.GetValue("lessVariables");
    // lessVariables.Type would return the JTokenType String
Karhgath
  • 1,809
  • 15
  • 11
  • This post seems to think otherwise http://stackoverflow.com/questions/12730280/posting-a-jobject-to-an-action – DrSammyD Jan 13 '14 at 18:52
  • As I've said, in the link you posted it is the root object that has been stringified, which works great. However, in the question above it's a value inside the root object; by default the WebApi framework won't parse this automatically, it will simply try to assign the lessVariables string to a JObject which won't work without parsing. – Karhgath Jan 13 '14 at 19:01
  • Oh, I see. Thanks, I'll just work with that I guess. – DrSammyD Jan 13 '14 at 19:07
  • You could also try to remove the JSON.stringify on lessVariables and simply put the raw Json, though I'm not sure WebApi will do the parsing automatically on multiple parameters from the Body. – Karhgath Jan 13 '14 at 19:12