Search code examples
c#.net-coremediatypeformatterjil

Not able to use JIL Serializer ExcludeNulls Option


I am not able to use JIL's Exclude Null option. Instead, I get an exception:

JIL.DeserializationException: 'Expected digit'

Below are code snippets.

public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
{
    if (context == null) throw new ArgumentNullException(nameof(context));

    var request = context.HttpContext.Request; if (request.ContentLength == 0)
    {
        if (context.ModelType.GetTypeInfo().IsValueType)
            return InputFormatterResult.SuccessAsync(Activator.CreateInstance(context.ModelType));
        else return InputFormatterResult.SuccessAsync(null);
    }

    var encoding = Encoding.UTF8;//do we need to get this from the request im not sure yet 

    using (var reader = new StreamReader(context.HttpContext.Request.Body))
    {
        var model =  Jil.JSON.Deserialize(reader, context.ModelType, Jil.Options.ExcludeNulls);
        return InputFormatterResult.SuccessAsync(model);
    }
}

1) Model type

public class PaymentTypeBORequest
{   
    public int pkId { get; set; }        
    public string description { get; set; }
    public bool isSystem { get; set; }
    public bool isActive { get; set; }           
}

2) JSON String:

{
    "pkId":null,
    "description": "Adjustment",
    "isSystem": true,
    "isActive": true
}

Solution

  • The description for the excludeNulls option is:

    whether or not to write object members whose value is null

    (emphasis mine)

    This suggests that it only affects serialisation operations and not deserialisation operations.

    When serialising an object with excludeNulls set to true, Jil will not write properties to the JSON if they have null values. In your example, you're deserialising into a PaymentTypeBORequest object, which itself does not support null values for the pkId property, as it's not nullable.

    In order to resolve your specific issue, you can simply set pkId to be a nullable int, like so:

    public class PaymentTypeBORequest
    {   
        public int? pkId { get; set; }
        ...
    }
    

    If you want to also allow null for the non-nullable isSystem and isActive properties, you can perform the same operations on those fields.