Search code examples
json.net-corejson.netazure-functionsapi-design

How to deal with mapping intentional NULL values passed through JSON?


Summary

Let's say I am designing an API to do a SQL Server SELECT Query. I have a couple required parameters and some optional parameters. However, if a null value is sent in the payload, this is correct and intentional, but I am unable to tell the difference in the current way I am deserializing the JSON. The value of the property I am deserializing to will be null by default. My issue is that I am unable to tell if it even got filled out or not as there is no marker for this.

Example

In the current way that I am doing this(example below), I am unable to differentiate if a user wants to:

  1. Actually look for a null value
  2. Remove the null value from serialization if the user is not interested looking up the particular field
using Newtonsoft.Json;

namespace test
{
    public class SomeClass
    {
        public string RequiredProperty {get;set;}
        public string RequiredProperty2 {get;set;}
        public string OptionalProperty3 {get;set;}

        public SomeClass(){}

    }

    class Program
    {
        static void Main(string[] args)
        {   
            // Example JSON payloads
            string JsonExample1 = @"
            {
                ""RequiredProperty"":""search"",
                ""RequiredProperty2"":""this"",
                ""OptionalProperty3"":null
            }";

            string JsonExample2 = @"
            {
                ""RequiredProperty"":""search"",
                ""RequiredProperty2"":""this""
            }";
            
            // Deserializing JsonExample1
            SomeClass sc1 = JsonConvert.DeserializeObject<SomeClass>(JsonExample1);

            // Deserializing JsonExample2 - identical to Example1 even though the INTENTION is completely different
            SomeClass sc2 = JsonConvert.DeserializeObject<SomeClass>(JsonExample2);

            // Now, using the model, I am unable to tell what the user's intentions actually were.
        }
    }
}   

Questions

1. Is my approach to this problem even correct?
  • I attempted to use Attributes to create and "IsSet" tag, but found out that was useless as it is attached to the type and cannot be changed at runtime.
  • Should I just leave the default value of the json as some kind of special string (i.e. "##notset##")?
  • Is there a best practice for this sort of thing? Any examples you guys can think of?
2. Is even proper to have optional parameters passed through JSON? I opted to use JSON payloads for everything because the company I work at has these insane payloads that need to be passed.

Solution

  • The comment provided by Andy is correct, I also don't know the difference between the two you mentioned in your question. I think the value of OptionalProperty3 is null is same with OptionalProperty3 is not-set.

    If you still want to distinguish between them, here I can provide a workaround for your reference. Replace the null in JsonExample1 with "null" string, please refer to my code below: enter image description here enter image description here