Проверка исправления JSON .Net Core

Кто-нибудь нашел хороший способ использовать аннотации данных, чтобы предотвратить обновление определенных свойств в документе исправления json.

Модель:

 public class Entity
 {
    [DoNotAllowPatchUpdate]
    public string Id     { get; set; }

    public string Name   { get; set; }

    public string Status { get; set; }

    public string Action { get; set; }
 }

Логика:

var patchDoc = new JsonPatchDocument<Entity>();
patchDoc.Replace(o => o.Name, "Foo");

//Prevent this from being applied
patchDoc.Replace(o => o.Id, "213");

patchDoc.ApplyTo(Entity);

Логический код — это всего лишь пример того, как может выглядеть документ с исправлениями, исходящий от клиента, который просто генерируется на C# для целей быстрого тестирования.


person Hizzy    schedule 27.04.2018    source источник


Ответы (2)


Я написал метод расширения для JsonPatchDocument; вот сокращенный вариант:

public static void Sanitize<T>(this Microsoft.AspNetCore.JsonPatch.JsonPatchDocument<T> document) where T : class
{
    for (int i = document.Operations.Count - 1; i >= 0; i--)
    {
        string pathPropertyName = document.Operations[i].path.Split("/", StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();

        if (typeof(T).GetProperties().Where(p => p.IsDefined(typeof(DoNotPatchAttribute), true) && string.Equals(p.Name, pathPropertyName, StringComparison.CurrentCultureIgnoreCase)).Any())
        {
            // remove
            document.Operations.RemoveAt(i); 

            //todo: log removal
        }
    }
}

Добавьте минимальный атрибут:

[AttributeUsage(AttributeTargets.Property)]
public class DoNotPatchAttribute : Attribute

Примените атрибут к свойствам вашего класса:

public class SomeEntity
{
    [DoNotPatch]
    public int SomeNonModifiableProperty { get; set; }
    public string SomeModifiableProperty { get; set; }
}

Затем вы можете вызвать его перед применением преобразования:

patchData.Sanitize<SomeEntity>();

SomeEntity entity = new SomeEntity();

patchData.ApplyTo(entity);
person RobertMGlynn    schedule 27.01.2020
comment
Мне нравится, как этот метод молча игнорирует недопустимые свойства в запросе, но при этом использует действительные. Для меня это то, что должен делать API, если в документации четко указано, что вы можете и что не можете делать в PATCH. - person smurtagh; 30.06.2021

Вы можете создать свой собственный Attribute. Что-то типа :

DoNotAllowPatchUpdate:Attribute{}

public class Entity
 {
    [DoNotAllowPatchUpdate]
    public string Id     { get; set; }

    public string Name   { get; set; }

    public string Status { get; set; }

    public string Action { get; set; }
 }

И затем проверьте это, например:

    var notAllowedProperties = typeof(Entity).GetProperties()
      .Where(x => Attribute.IsDefined(x, typeof(DoNotAllowPatchUpdate)))
      .Select(x => x.Name).ToList();

теперь, прежде чем обновлять их, вы можете проверить notAllowedProperties.

person 3xGuy    schedule 27.04.2018
comment
Не будет ли этот код всегда возвращать список имен только одного «идентификатора», что на самом деле не мешает применению изменения свойства. Это может помочь логическому блоку, проверяющему patchDoc. Я полагаю, вы могли бы использовать имена в notAllowedProperties и посмотреть, появляется ли имя в пути операции, а затем удалить эту операцию. Я опубликую свой код, когда закончу - person Hizzy; 28.04.2018