Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize a JObject the same way as an object with Json.NET?

Tags:

c#

json.net

How do I control the serialization of a JObject to string?

I have some APIs that return a JObject and I usually apply some changes and persist or return them. I want to avoid persisting null properties and apply some additional formatting, but JsonConvert seems to completely ignore my settings.

Here is the sample of the problem:

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

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

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

Posting { "Foo": "Foo", "Bar": null }:

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

I want the JObject method to return the same output json as if I were using an object. How do I achieve this without creating helpers? Is there a way to serialize the JObject using the same settings?

like image 725
Natan Avatar asked Oct 25 '16 15:10

Natan


People also ask

How do you serialize and deserialize an object in C# using JSON?

It returns JSON data in string format. In Deserialization, it does the opposite of Serialization which means it converts JSON string to custom . Net object. In the following code, it calls the static method DeserializeObject() of the JsonConvert class by passing JSON data.

How do you serialize an array in JSON?

To serialize a collection - a generic list, array, dictionary, or your own custom collection - simply call the serializer with the object you want to get JSON for. Json.NET will serialize the collection and all of the values it contains.

What is JSON serialize object?

JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object). If you serialize this result it will generate a text with the structure and the record returned.


1 Answers

The only way I was able to do this is by first converting the JObject to a string, then deserializing that string into an ExpandoObject (don't deserialize to object because you'll get back a JObject). The ExpandoObject is like a dictionary, which will cause JsonConvert to actually invoke the configured name case strategy. I'm not sure why the author of Newtonsoft.Json didn't handle JObject types the same way as they seem to be doing for dictionary types, but at least this work around works.

Example:

// Construct a JObject.
var jObject = JObject.Parse("{ SomeName: \"Some value\" }");

// Deserialize the object into an ExpandoObject (don't use object, because you will get a JObject).
var payload = JsonConvert.DeserializeObject<ExpandoObject>(jObject.ToString());

// Now you can serialize the object using any serializer settings you like.
var json = JsonConvert.SerializeObject(payload, new JsonSerializerSettings
{
    ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new CamelCaseNamingStrategy
        {
            // Important! Make sure to set this to true, since an ExpandoObject is like a dictionary.
            ProcessDictionaryKeys = true,
        }
    }
}
);

Console.WriteLine(json); // Outputs: {"someName":"Some value"}

I picked-up the trick with the ExpandoObject here: JObject & CamelCase conversion with JSON.Net

like image 172
Sipke Schoorstra Avatar answered Sep 21 '22 16:09

Sipke Schoorstra