0

Following is my Json serialization code with CustomResolver, check the difference between Actual and Expected results at the end. I am not able to remove the empty elements from the final result. There's an option available here, but in my real application, which use ASP.Net Web API, I don't have the liberty to call JsonConvert.SerializeObject, it is called automatically, probably need a way to do it in the Custom Contract Resolver, any help / pointer would be great

void Main()
{
    var cbList = new List<CustomerBusiness>();

    cbList.Add(new CustomerBusiness { Id = null, Name = null, PhoneNumber = null });
    cbList.Add(new CustomerBusiness { Id = 1, Name = null, PhoneNumber = null });
    cbList.Add(new CustomerBusiness { Id = null, Name = "Mrinal", PhoneNumber = null });
    cbList.Add(new CustomerBusiness { Id = null, Name = null, PhoneNumber = "9886623261" });
    cbList.Add(new CustomerBusiness { Id = null, Name = null, PhoneNumber = null });
    cbList.Add(new CustomerBusiness { Id = null, Name = null, PhoneNumber = null });

    var serializedData = JsonConvert.SerializeObject(cbList, Newtonsoft.Json.Formatting.Indented,new JsonSerializerSettings { ContractResolver = new CustomResolver() });

    serializedData.Dump();
}

public class CustomResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> retval = base.CreateProperties(type, memberSerialization);

        retval = retval.Select(p =>
        {
            p.PropertyName = char.ToLower(p.PropertyName[0]) + string.Join("", p.PropertyName.Skip(1));
            p.NullValueHandling = NullValueHandling.Ignore;
            return p;
        }).ToList();

        return retval;
    }
}

public class CustomerBusiness
{
    public int? Id { get; set; }

    public string Name { get; set; }

    public string PhoneNumber { get; set; }
}

Actual Result:

[
  {},
  {
    "id": 1
  },
  {
    "name": "Mrinal"
  },
  {
    "phoneNumber": "9886623261"
  },
  {},
  {}
]

Expected Result:

[
  {
    "id": 1
  },
  {
    "name": "Mrinal"
  },
  {
    "phoneNumber": "9886623261"
  }
]
Mrinal Kamboj
  • 11,300
  • 5
  • 40
  • 74
  • Dear Down voter, atleast the basic courtesy that why the down vote, in case you really have confidence in your point – Mrinal Kamboj Aug 23 '17 at 00:16
  • Possible duplicate of [Can Newtonsoft Json.NET skip serializing empty lists?](https://stackoverflow.com/questions/11320968/can-newtonsoft-json-net-skip-serializing-empty-lists) – Mehdi Dehghani Mar 31 '19 at 05:05

1 Answers1

1
var serializedData = JsonConvert.SerializeObject(
    cbList,
    Newtonsoft.Json.Formatting.Indented,new JsonSerializerSettings { ContractResolver = new CustomResolver() });

should possibly be replaced with:

var serializedData = JsonConvert.SerializeObject(
    cbList.Where(z => z.Id != null || z.Name != null || z.PhoneNumber != null),
    Newtonsoft.Json.Formatting.Indented,new JsonSerializerSettings { ContractResolver = new CustomResolver() });

The Where clause will ensure that you serialise only the 'non-null' data.

mjwills
  • 23,389
  • 6
  • 40
  • 63
  • This is good workaround +1, but I cannot use it my case, firstly I don't call SerilaizeObject call as mentioned in the original post and also same data can be exposed for other requirements, so its not necessary that removing all null data is expected / required in all the API calls – Mrinal Kamboj Aug 22 '17 at 15:50
  • You need to make your code in your post as **close as possible** to your real code to make it easier for us to help you. Note that my answer is not **dependent** on the `JsonConvert.SerializeObject` call - the important bit is the `Where` call. – mjwills Aug 22 '17 at 22:01
  • I think this is closest I could have been using console, with all important details already mentioned there, what do you think is the missing part, your solution predominantly focus on pruning the collection, where I want it to be done during serialization, since null data removal may not be allowed for real use case. In case you have a serialization option then please provide. I am not sure, is this the reason for down vote – Mrinal Kamboj Aug 23 '17 at 00:10
  • `where I want it to be done during serialization, since null data removal may not be allowed for real use case` Can you talk us through why null data removal may not be allowed for real use case? – mjwills Aug 23 '17 at 00:23
  • Since the same data is consumed by multiple callers, where some want to display all null or empty records with separate message in their Ui control, to provide more information, that's why optional serialization is preferred over modifying the data source. I hope this clarifies the specific use-case. I have anyway focused only on getting a serialization specific solution, where a custom contact resolver can do the job – Mrinal Kamboj Aug 23 '17 at 00:43