How to apply partial ModelState validation for JsonPatch in ASP.NET Core

538 views Asked by At

I was struggling with an issue that if you use data annotations for model validation in ASP.NET Core and you run patchDoc.ApplyTo(newData); and then if (!TryValidateModel(newData)) you got model validation errors for operations not included in the patch document.

If a property was null before and it has a [Required] attribute it will give a model state validation error although I didn't include that property in the patch document.

1

There are 1 answers

0
BigThinker On

My starting solution is to add an extension method for ModelStateDictionary that looks like this

public static void ApplyPatchDocument<T>(this ModelStateDictionary modelState, JsonPatchDocument<T> patchDoc) where T : class
    {
        if (modelState == null)
        {
            throw new ArgumentNullException(nameof(modelState));
        }

        if (patchDoc == null)
        {
            throw new ArgumentNullException(nameof(patchDoc));
        }

        var modelStateKeys = modelState.Keys.ToList();
        for (var i = modelStateKeys.Count - 1; i >= 0; i--)
        {
            var modelStateKey = modelStateKeys[i];
            var modelStateEntry = modelState[modelStateKey];
            if (modelStateEntry.Errors.Count > 0
                && !patchDoc.Operations
                    .Any(op => op.path
                        .TrimStart('/')
                        .Replace('/', '.')
                        .IndexOf(modelStateKey, StringComparison.OrdinalIgnoreCase) > -1))
            {
                modelState.Remove(modelStateKey);
            }
        }
    }

There are issues with this method, for example when you want to change an array property this won't work as it is but it's a good start. Hopefully it helps someone! :)