jeudi 23 juillet 2020

Compare 2 of the same .NET objects and detect properties that are missing from one but present in the other

I have a .NET Core Web API + Entity Framework Core, and I am trying to cater for clients sending incomplete / partial JSON Payloads to update an existing Customer (and associated Entities) record. For instance, they may not send the date_of_birth attribute at all, so would like this to mean that the date_of_birth already in the database is not updated at all. At the moment I have the following method,

private static T CheckUpdateObject<T>(T dbEntity, T updateEntity) where T : class 
{
    foreach (var property in updateEntity.GetType().GetProperties())
    {
        if (property.GetValue(updateEntity, null) == null)
        {
            Console.WriteLine($"Entity property {property.Name} is NULL. It will not be updated.");
            property.SetValue(updateEntity, dbEntity.GetType().GetProperty(property.Name)
            .GetValue(dbEntity, null));
        }
    }
    return updateEntity;
}

Which ensures that if for example, date_of_birth is passed as Null, we overwrite it with the value already in the database before saving the Entity (and if other values are non Null, we accept those new values). However, I am unclear how to extend this to cater for when the attribute is missing completely? So, the dbEntity (taken from the existing record in the Database) will have a date_of_birth attribute, but the incoming updateEntity object may not. In this case, I'd like to leave the attribute alone.

I want this to be generic enough to apply to any attribute that is absent from the incoming payload. E.g. if the client wants to update address_line_2 of the customers Address, they don't need to pass

Address:
 address_line_1: 23 spooner
 address_line_2: some new value
 post_code: 3030

They can just pass

Address:
 address_line_2: some new value 

And be comfortable that address line 1 and post code won't be touched. My method works if they pass

Address: 
 address_line_1: null
 address_line_2: some new value
 post_code: null

But I think it's a bit cumbersome, and NULLs attributes not passed in at all.





Aucun commentaire:

Enregistrer un commentaire