Newtonsoft.json: JObject ignores JsonSerializerSettings during serialization

Created on 24 Oct 2016  路  10Comments  路  Source: JamesNK/Newtonsoft.Json

Using settings.NullValueHandling = NullValueHandling.Ignore, returning the following object from an asp.net core controller:

return new
{
    Foo = (string)null,
    Bar = "bar",

    Baz = JObject.FromObject(new
    {
        Foo = (string)null,
        Bar = "bar"
    })
};

The json generated is:

{  
   "bar":"bar",
   "baz":{  
      "Foo":null,
      "Bar":"bar"
   }
}

See that the null value is included in the JObject, but not in the object directly. Also, the property name doesn't have the first letter lowercased per asp.net core defaults. The serializer seems to be ignoring the settings for JObjects completely.

I'm using 9.0.1

Most helpful comment

Hi. Apparently no one has any idea how to achieve this. Would you please be kind enough to answer there?

http://stackoverflow.com/questions/40244395/how-to-serialize-a-jobject-the-same-way-as-an-object-with-json-net

Thanks.

All 10 comments

No settings are being passed to FromObject

Hi. I'm not sure I'm following. In order to get the output serialized correctly, I'm supposed to pass the settings to the parser? Doesn't make much sense, since we don't always get to control how jobjects are created.

You do get control. Ask on stackoverflow

You do get control. Ask on stackoverflow

I looked around on SO before posting this bug report. The only answer there creates a helper that manually removes null tokens from JObjects before output. Doesn't look like what you're referring to.

I still feel there is something wrong here, so I'll insist one last time.

Consider the following code:

// startup.cs has the following
services.AddMvc().AddJsonOptions(o =>
{
    o.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});

// actual sample
public class SampleController : Controller
{
    JsonSerializerSettings _settings = new JsonSerializerSettings
    {
        NullValueHandling = NullValueHandling.Ignore
    };

    [HttpPost]
    [Route("object")]
    public object PostObject([FromBody] SomeObject data)
    {
        return JsonConvert.SerializeObject(data, _settings);
    }

    [HttpPost]
    [Route("jobject")]
    public object PostJObject([FromBody] JObject data)
    {
        return JsonConvert.SerializeObject(data, _settings);
    }

    [HttpGet]
    [Route("jobject-parse")]
    public object GetJObjectParse()
    {
        var json = @"{ ""Foo"": ""Foo"", ""Bar"": null }";
        var data = JObject.Parse(json, new JsonLoadSettings { /* nothing here to control formatting */ });
        return JsonConvert.SerializeObject(data, _settings);
    }

    public class SomeObject
    {
        public string Foo { get; set; }
        public string Bar { get; set; }
    }
}

I'm posting { "Foo": "Foo", "Bar": null },

  • /object returns {"Foo":"Foo"}
  • /jobject returns {"Foo":"Foo","Bar":null}
  • /jobject-parse returns {"Foo":"Foo","Bar":null}

This definitely is weird. And the main reason it's weird is that I'm manually calling SerializeObject passing the output settings.

It seems JObject ignores the settings during the parsing, and also ignores it during the output formatting.

Even if there is a bug at the parsing side, I'd argue that it makes no sense to control the _output formatting_ of an object during the parsing phase. But from what I can see, ASP.NET always uses the defined settings when creating the JsonSerializer to parse the body. Also, there is no overload of JObject.Parse that accepts a JsonSerializerSettings object.

Something is strange here. If as the creator of this this really makes sense for you, I ask you politely please just give a brief explanation on if the JObject is not supposed to be used this way, or there is another way to control the output of JObject using the JsonSerializerSettings we have.

A JObject isn't serialized. It is written as is.

Yes you can control the output of a JObject. Like I said, ask on stackoverflow. Someone will help you.

Hi. Apparently no one has any idea how to achieve this. Would you please be kind enough to answer there?

http://stackoverflow.com/questions/40244395/how-to-serialize-a-jobject-the-same-way-as-an-object-with-json-net

Thanks.

@nvivo, did you find out how to do this? I've run into the same issue and I can't work it out either.

@nizmow I ended up manually doing the things I needed by cloning the JObject, walking the json tree and applying the changes (like changing things to camelCase, removing nulls, etc) before calling ToString().

@JamesNK Would it be possible to add an option to JObject.ToString() or just some other method on JObject that removes null values? https://stackoverflow.com/questions/33027409/json-net-serialize-jobject-while-ignoring-null-properties includes example code for this. However, it seems that removing null properties is something common enough that there should be some kind of helper method included with JObject by default. It seems like an oversight to me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davidfowl picture davidfowl  路  49Comments

Richard-Payne picture Richard-Payne  路  13Comments

TylerBrinkley picture TylerBrinkley  路  16Comments

XeonG picture XeonG  路  12Comments

manuc66 picture manuc66  路  12Comments