Reputation:
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
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
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
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