JSON 补丁验证 .Net Core
JSON Patch Validation .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# 中生成
您可以创建自己的 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
。
我为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
将属性应用于您的 class 属性:
public class SomeEntity
{
[DoNotPatch]
public int SomeNonModifiableProperty { get; set; }
public string SomeModifiableProperty { get; set; }
}
然后您可以在应用转换之前调用它:
patchData.Sanitize<SomeEntity>();
SomeEntity entity = new SomeEntity();
patchData.ApplyTo(entity);
虽然问题特别询问了关于使用注释通过 JsonPatchDocuments 限制更新,但我认为添加另一种方法可能对某些人有所帮助。
我通常会创建一个 update-specific 模型,其中只有我希望允许更新的字段。那么更新Id是不可能的,例如:
public class UpdateEntityModel
{
public string Name { get; set; }
public string Status { get; set; }
public string Action { get; set; }
}
我的 controller/function 收到类型 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>
专门验证更新模型。
有没有人找到使用数据注释来防止在 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# 中生成
您可以创建自己的 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
。
我为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
将属性应用于您的 class 属性:
public class SomeEntity
{
[DoNotPatch]
public int SomeNonModifiableProperty { get; set; }
public string SomeModifiableProperty { get; set; }
}
然后您可以在应用转换之前调用它:
patchData.Sanitize<SomeEntity>();
SomeEntity entity = new SomeEntity();
patchData.ApplyTo(entity);
虽然问题特别询问了关于使用注释通过 JsonPatchDocuments 限制更新,但我认为添加另一种方法可能对某些人有所帮助。
我通常会创建一个 update-specific 模型,其中只有我希望允许更新的字段。那么更新Id是不可能的,例如:
public class UpdateEntityModel
{
public string Name { get; set; }
public string Status { get; set; }
public string Action { get; set; }
}
我的 controller/function 收到类型 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>
专门验证更新模型。