2

Apply DefaultValue to every string properties.

Context:

The Following class are automatically generated. And Editing them to add those property is a burden. As generated class is quite big, and generated code has a lot of existing property etc. I made a program that open the CS file and use some regex to add the property. but still have to maintain the programme to match the generated file name.


With Json.Net, in order to hide empty string in the serialisation result I have to define the default value of those string with [DefaultValue("")].

In the following exemple we have some class and nested class. The aim is to hide the empty string in Bar when serialising a Foo item.

public class Foo
{
    public int Prop1;
    [DefaultValue("")]
    public string Prop2;
    public int? Prop3;
    public Bar Prop4;
    public Bar[] Prop5;
};

public class Bar
{
    public int Prop1;
    public string Prop2;
    public int? Prop3;
};

public void NullOrEmptyStringTerminator()
{
    var bar = new Bar { Prop1 = 0, Prop2 = "", Prop3 = 0 };
    var bar2 = new Bar { Prop1 = 0, Prop3 = 0 };

    var inputs = new[] {
       new Foo{ Prop1= 1, Prop2="", Prop4= bar, Prop5 = new []{bar} },
       new Foo{ Prop1= 1, Prop4= bar, Prop5 = new []{bar2} },
    };

    var jsonResults = 
            inputs
                .Select(x =>
                    new
                    {
                        Item = x,
                        NormalSerialisation =
                            JsonConvert.SerializeObject(
                                x,
                                Formatting.Indented,
                                new JsonSerializerSettings { }
                            ),
                        CustomSerialisation =
                             JsonConvert.SerializeObject(
                                x,
                                Formatting.Indented,
                                new JsonSerializerSettings
                                {
                                    NullValueHandling = NullValueHandling.Ignore,
                                    DefaultValueHandling = DefaultValueHandling.Ignore,
                                })
                    }
                ).ToList();
}

Test Case:

class Foo : 
  int    Prop1 -> Real value 1
  string Prop2 -> No value either "" or null
  int?   Prop3 -> No value null
  Bar    Prop4 -> Real value Bar
  Bar[]  Prop5 -> Real value Bar[]

class Bar :
  int    Prop1 -> No value 0.
  string Prop2 -> Same test than Foo.Prop2
  int?   Prop3 -> Real value 0; Not null

The expect result is for both of the input Json.

{
  "Prop1": 1,
  "Prop4": {
    "Prop3": 0
  },
  "Prop5": [
    {
      "Prop3": 0
    }
  ]
}
xdtTransform
  • 1,986
  • 14
  • 34
  • `DefaultValueHandling`, `NullValueHandling`, and `[DefaultValue("")]`, are already present in this question. I will update with a C# fiddle and the print of CustomSerialisation. When I get to a PC – xdtTransform Jan 16 '19 at 14:57
  • Yeah, you already using `DefaultValueHandling`, but you forgot to add `DefaultValueAttribute` to `Prop2` in `Bar`. Then it's only `Prop1` and `Prop3` (when set to `0`). `Foo` is working, right? – Sinatr Jan 16 '19 at 15:06
  • If you can't modify `Bar`, then you have to [write custom converter for properties containing `Bar`](https://stackoverflow.com/q/18521970/1997232). – Sinatr Jan 16 '19 at 15:10
  • No. Not forget. I have a lot of class. And need some kind of generalisation – xdtTransform Jan 16 '19 at 15:11
  • Possible duplicate of [Remove empty string properties from json serialized object](https://stackoverflow.com/questions/41287224/remove-empty-string-properties-from-json-serialized-object) – Mat Jan 16 '19 at 15:25
  • I guess we have a [xy problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) here. However now that is more clear that these classes are "automatically generated" how to you generate them? Do you have any influence in the generation process? Which module/software/whatever generate your classes? – Mat Jan 17 '19 at 16:06

1 Answers1

0

You have to set the DefaultValueAttribute in your Bar class. A alternative would also be to set the property to null.

https://dotnetfiddle.net/aEoBlT

using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
        var inputs = new List<object>()
        {new Foo{Prop2 = "" , Bar = new Bar()}};
        foreach (object input in inputs)
        {
            string NormalSerialisation = JsonConvert.SerializeObject(input, Formatting.Indented, new JsonSerializerSettings{});
            string CustomSerialisation = JsonConvert.SerializeObject(input, Formatting.Indented, new JsonSerializerSettings{NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore});
            Console.WriteLine("normal:");
            Console.WriteLine(NormalSerialisation);
            Console.WriteLine("custom:");
            Console.WriteLine(CustomSerialisation);
        }
    }

    public class Foo
    {

        public string Prop2
        {
            get;
            set;
        }

        public Bar Bar
        {
            get;
            set;
        }
    }

    public class Bar
    {
        [DefaultValue("")]
        public string Prop2;
    }
}

Output:

normal:
{
  "Prop2": "",
  "Bar": {
    "Prop2": null
  }
}
custom:
{
  "Prop2": "",
  "Bar": {}
}
Mat
  • 1,960
  • 5
  • 25
  • 38