user11466982
user11466982

Reputation:

How to remove unwanted string properties from JSON

Suppose my input is following JSON:

{obj: { x: "", y: "test str" }, myStr: "Hi"}

I would like to remove all empty strings and strings with a value of N/A so that the output becomes:

{obj: { y: "test str" }, myStr: "Hi"}

Note the above input is just a sample input file.

I tried to write some code :

var serializerSettings = new JsonSerializerSettings 
{ 
    NullValueHandling = NullValueHandling.Ignore, 
    DefaultValueHandling = DefaultValueHandling.Ignore 
};

But I'm not able to get the desired output.

Upvotes: 2

Views: 2031

Answers (3)

Brian Rogers
Brian Rogers

Reputation: 129687

If you're using a class model to deserialize into, you can use a custom ContractResolver to filter out the unwanted properties on serialization:

class CustomContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var prop = base.CreateProperty(member, memberSerialization);
        if (prop.PropertyType == typeof(string) && prop.Readable)
        {
            prop.ShouldSerialize = obj =>
            {
                string val = (string)prop.ValueProvider.GetValue(obj);
                return !string.IsNullOrEmpty(val) && !val.Equals("N/A", StringComparison.OrdinalIgnoreCase);
            };
        }
        return prop;
    }
}

Then use it like this:

var obj = JsonConvert.DeserializeObject<YourClass>(inputJson);

var serializerSettings = new JsonSerializerSettings
{
    ContractResolver = new CustomContractResolver
    {
        NamingStrategy = new CamelCaseNamingStrategy()
    }
};

string outputJson = JsonConvert.SerializeObject(obj, serializerSettings);

Working demo here: https://dotnetfiddle.net/zwpj7I


Alternatively, you can remove the unwanted properties without a class model like this:

var jo = JObject.Parse(inputJson);

var unwantedProperties = jo.Descendants()
    .OfType<JProperty>()
    .Where(p => p.Value.Type == JTokenType.Null ||
                (p.Value.Type == JTokenType.String &&
                 ((string)p.Value == string.Empty ||
                  string.Equals((string)p.Value, "N/A", StringComparison.OrdinalIgnoreCase))))
    .ToList();

foreach (var prop in unwantedProperties)
{
    prop.Remove();
}

string outputJson = jo.ToString(Formatting.None);

Demo: https://dotnetfiddle.net/QLhDK4

Upvotes: 3

Alex
Alex

Reputation: 26

Please take a look at ShouldSerialize. You should declare a method like this in the class containing property "x":

public bool ShouldSerializex()
{
    return x != "" && x != "N/A";
}

Upvotes: 0

NajiMakhoul
NajiMakhoul

Reputation: 1716

to ignore default empty string using DefaultValueHandling you need to add DefaultValue to x property

[DefaultValue("")]
public string x{ get; set; }

Update:

Here is a link to a working dotnetfiddle

using System;
using Newtonsoft.Json;
using System.ComponentModel;
                    
public class Program
{
        
    public static void Main()
    {
        //var myClass = new MyClasss();
        //var myObj = new Obj();
        
        //myObj.x="";
        //myObj.y="test str";
        
        //myClass.myStr = "Hi";
        //myClass.obj= myObj;
        
        string json = @"{obj: { x: '', y: 'test str' }, myStr: 'Hi'}";
        MyClasss myClass = JsonConvert.DeserializeObject<MyClasss>(json);

        var settings = new JsonSerializerSettings();
        
        settings.NullValueHandling = NullValueHandling.Ignore;
        settings.DefaultValueHandling = DefaultValueHandling.Ignore;
        
        
        Console.WriteLine(JsonConvert.SerializeObject(myClass, settings));
    }
}

    public class Obj    {
        [DefaultValue("")]
        public string x { get; set; } 
        [DefaultValue("")]
        public string y { get; set; } 

    }

    public class MyClasss    {
        public Obj obj { get; set; } 
        [DefaultValue("")]
        public string myStr { get; set; } 

    }

Upvotes: 0

Related Questions