0

I thought this would have been easy but I am having issues ticking all the boxes that I need in this.

I need to

  • Serialize an object to Json
  • Ignore any properties not set
  • Use the ENum names instead of integer values

I have generated all the models for this using the Open API Generator based on a .yaml spec.

My first attempt was to get a bit of code from what looks like an old serializer

let json<'t> (myObj:'t) =   
    use ms = new MemoryStream() 
    let serialiser: DataContractJsonSerializer = new DataContractJsonSerializer(typeof<'t>)
    let settings: DataContractJsonSerializerSettings = new DataContractJsonSerializerSettings()
    
    (new DataContractJsonSerializer(typeof<'t>)).WriteObject(ms, myObj) 
    Encoding.Default.GetString(ms.ToArray()) 

This function actually does everything fine - except it copiess the enum numbers instead of names and I can't see an option to make this happpen.

My other attempt is using System.Text.Json.JsonSerializer:

    let options 
        = new JsonSerializerOptions(
            )
    options.DefaultIgnoreCondition <- JsonIgnoreCondition.WhenWritingDefault
    options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
    let jsonString:string = JsonSerializer.Serialize(shipmentRequest, options)

I have tried a few different things ( including excluding the Enum converter ) and I always get the following error.

Unable to cast object of type 'System.Int32' to type 
'System.Nullable`1[Zimpla.Model.ExpressPackageReference+TypeCodeEnum]'

The specific Object ( roughly ) that it is having an issue with is:

[DataContract(Name = "ExpressPackageReference")]
public partial class ExpressPackageReference : IEquatable<ExpressPackageReference>, IValidatableObject
{

......etc

        [DataMember(Name = "typeCode", EmitDefaultValue = false)]
    public TypeCodeEnum? typeCode 
    { 
        get{ return _typeCode;}
        set
        {
            _typeCode = value;
            _flagtypeCode = true;
        }
    }

This particular property is not even set so it should be skipping over it theoretically. It is possible that I am not generating the object correctly

Martin Thompson
  • 3,415
  • 10
  • 38
  • 62
  • Can you provide an example of an object and what it should look like when serialized? – Andreas Ågren Sep 03 '21 at 06:46
  • @AndreasÅgren Thanks - I have just updated the text – Martin Thompson Sep 03 '21 at 07:12
  • Have you considered simply doing [de]serialization manually? Unless you have a big and/or a very volatile API, the time saved using a ready made serializer might be less than the time wasted learning and configuring it. – Guran Sep 03 '21 at 08:06
  • @Guran - that code is all generated using Open API generator ( it's actually consuming the DHL API - and they provide a .yaml file for definitions ) . So I am not sure if I understand what you mean by a "ready made serializer" . I thoughts the lines of code at the top using System.Text.Json.JsonSerializer was ready made. – Martin Thompson Sep 03 '21 at 08:50
  • @MartinThompson Sorry for frame-challenge your question a bit. If generated code gives you trouble, than the solution might be NOT to generate code but write it manually. (Not saying that code generation might not be the correct choice, just that it should be a concious one) – Guran Sep 03 '21 at 08:59

1 Answers1

1

Without understanding all the details here, I think you are asking how you can serialize an object to json while omitting all properties that are null using System.Text.Json.

To accomplish that you have to set the following option:

options.IgnoreNullValues <- true

Here are the docs for this option: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.ignorenullvalues?view=net-5.0#System_Text_Json_JsonSerializerOptions_IgnoreNullValues

Andreas Ågren
  • 3,879
  • 24
  • 33