Search code examples
c#asp.net-core.net-coremodel-binding

How to differentiate between null and non existing data in JSON in Asp.Net Core model binding?


I want to differentiate between these two json inputs in an action in Asp.Net Core:

{
  "field1": null,
  "field2": null
}

and

{
  "field1": null,
}

I have an ordinary class like this in C#:

public class MyData
{
   public string Field1 { get; set;}
   public string Field2 { get; set;}
}

I want to run a partial update of an object that can accept null as the value, but when the field will not be in the input it means I don't want to update this field at all (something else from setting it to null).


Solution

  • This is what I ended up doing, as all other options seem to be too complicated (e.g. jsonpatch, model binding) or would not give the flexibility I want.

    This solution means there is a bit of a boilerplate to write for each property, but not too much:

    public class UpdateRequest : PatchRequest
    {
        public string Name
        {
           get => _name;
           set { _name = value; SetHasProperty(nameof(Name)); }
        }  
    }
    
    public abstract class PatchRequest
    {
        private readonly HashSet<string> _properties = new HashSet<string>();
    
        public bool HasProperty(string propertyName) => _properties.Contains(propertyName);
    
        protected void SetHasProperty(string propertyName) => _properties.Add(propertyName);
    }
    

    The value can then be read like this:

    if (request.HasProperty(nameof(request.Name)) { /* do something with request.Name */ }
    

    and this is how it can be validated with a custom attribute:

    var patchRequest = (PatchRequest) validationContext.ObjectInstance;
    if (patchRequest.HasProperty(validationContext.MemberName) {/* do validation*/}