0

I had to generate some classes from an xsd file. The classes and properties are generated correct with xml serialization annotation. The problem is that the decimal properties of a class are serialized with Newtonsoft.Json even are not populated. I would like to serialize only the decimal properties that are properly populated. Amount is part of SaleMessage For example:

class Amount
{
[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal RequestedAmount;

[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal CashBackAmount;

[System.Xml.Serialization.XmlAttributeAttribute()]
public decimal TipAmount;
}

//Usage
var amount = new Amount()
{
 RequestedAmount = 12.0
}

Using this structure it will always serialize all the properties like this {"RequestedAmount":12.0,"CashBackAmount":0.0,"TipAmount":0.0} Which is not the expected behaviour. The question is how can I modify the serialization to not parse the not set properties

 static string Serialize(SaleMessage saleMessage)
        {
            var serialize= JsonConvert.SerializeObject(saleToPoiMessage,
                new StringEnumConverter(),
                new IsoDateTimeConverter() { DateTimeFormat = DateTimeFormat });
            return serialize;
        }

Any help is appreciated :)

Alexandros Mor
  • 127
  • 3
  • 12
  • But it is the expected behavior. All properties exist. – BugFinder Jun 12 '19 at 08:32
  • This is the intended behavior. Json.NET has no way to know if a non-nullable value type value has been set or not. If you don't want this you can make your properties nullable or use conditional serialization, see [How to do Conditional Serialization using C# - NewtonSoft.Json](https://stackoverflow.com/q/42781725) or [How to force Newtonsoft Json to serialize all properties? (Strange behavior with “Specified” property)](https://stackoverflow.com/q/39223335). – dbc Jun 12 '19 at 08:35
  • [Related: How to ignore a property in class if null, using json.net](https://stackoverflow.com/questions/6507889/how-to-ignore-a-property-in-class-if-null-using-json-net). Although the title says "null" some answers also deal with non-null default values – A Friend Jun 12 '19 at 08:37
  • It should be possible to customize serializer. See [ContractResolver](https://www.newtonsoft.com/json/help/html/contractresolver.htm). But you will need to use custom attribute (e.g. [DefaultValueAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.defaultvalueattribute)) to set "not set properties" condition somehow. – Sinatr Jun 12 '19 at 08:50
  • I agree @BugFinder it is an expected behavior as the primitive types are not nullable – Alexandros Mor Jun 15 '19 at 07:28

3 Answers3

1

You can set the DefaultValueHandling setting to Ignore to suppress serialization of values that are equal to their default value.

var settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> 
    { 
        new StringEnumConverter(),
        new IsoDateTimeConverter() { DateTimeFormat = DateTimeFormat } 
    },
    DefaultValueHandling = DefaultValueHandling.Ignore
};

var json = JsonConvert.SerializeObject(saleMessage, settings);

Fiddle: https://dotnetfiddle.net/o32k0U

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
  • That's a really good answer! In my case I just made the primitive types null-able. I am not sure if it is a good practice but it worked. – Alexandros Mor Jun 15 '19 at 07:32
0

Since it's of type decimal primitive it will have some value by default. I think you need to implement the serializer utility Newtonsoft.Json uses - on your own. Where you will not include the decimal values of 0.0 (if this suits the business logic).

Another option is not to use the primitive class and then set up the property of removing null values while serializing. I believe you can set up this config parameter in Newtonsoft.

Check this: https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm

0

In my case I changed the primitive types to nullable.

public decimal? CashBackAmount {get; set;}

This worked for me. I prefer the @Brian Rogers answer. :)

Alexandros Mor
  • 127
  • 3
  • 12