8

有没有人找到一种使用数据注释来防止特定属性在 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# 中生成

4

3 回答 3

6

我为 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);
于 2020-01-27T19:27:29.577 回答
3

您可以创建自己的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.

于 2018-04-27T15:39:38.800 回答
0

尽管该问题专门询问了有关使用注释来限制通过 JsonPatchDocuments 进行更新的问题,但我认为添加另一种方法可能对某些人有所帮助。

我通常会创建一个特定于更新的模型,它只包含我希望允许更新的字段。那么就无法更新Id,例如:

public class UpdateEntityModel
{    
    public string Name { get; set; }

    public string Status { get; set; }

    public string Action { get; set; }
 }
 

我的控制器/函数接收类型的参数JsonPatchDocument<UpdateEntityModel>。我从数据库中获取所需的实体,将其属性映射到我的更新模型,将补丁应用到更新模型并验证结果。然后将其映射回实体以将更改持久保存在数据库中。

/* Fetch entity from db */


var updateEntityModel = MapEntityToUpdateModel(entity);
    
jsonPatchDocument.ApplyTo(updateEntityModel);

ValidateModel(updateEntityModel); // Using FluentValidation validator
     
MapUpdateModelBackToEntity(entity, updateEntityModel);


/* Persist entity in db */

我使用 FluentValidation,AbstractValidator<UpdateEntityModel>来专门验证更新模型。

于 2022-02-24T11:12:12.597 回答