(feature): simplify patch request fields management for frontend validation like zod
This commit is contained in:
parent
2e2036c90d
commit
eaa610a853
30
README.md
30
README.md
@ -1945,22 +1945,7 @@ var response = new PagedResponse<User>(users, totalCount: 100, pageNumber: 1, pa
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### **3. `PatchField<T>`**
|
#### **3. `PatchOperation`**
|
||||||
|
|
||||||
##### Summary
|
|
||||||
Represents a patch operation on a specific field or value, used for partial updates in Web APIs.
|
|
||||||
|
|
||||||
##### Usage
|
|
||||||
```csharp
|
|
||||||
var patchField = new PatchField<string> {
|
|
||||||
Operation = PatchOperation.Replace,
|
|
||||||
Value = "New Value"
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### **4. `PatchOperation`**
|
|
||||||
|
|
||||||
##### Summary
|
##### Summary
|
||||||
Enumerates the types of patch operations that can be performed on a field or collection.
|
Enumerates the types of patch operations that can be performed on a field or collection.
|
||||||
@ -2008,13 +1993,18 @@ Console.WriteLine($"Total Pages: {pagedResponse.TotalPages}");
|
|||||||
|
|
||||||
### Partial Updates Using PatchField
|
### Partial Updates Using PatchField
|
||||||
```csharp
|
```csharp
|
||||||
var patch = new PatchField<string> {
|
var patch = new SomePatchRequestModel {
|
||||||
Operation = PatchOperation.Replace,
|
Username = "Updated Name"
|
||||||
Value = "Updated Name"
|
|
||||||
|
Operations = new Dictionary<string, PatchOperation> {
|
||||||
|
{ "Username", PartchOperation.Replace }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Deconstruct the patch field
|
// Deconstruct the patch field
|
||||||
var (operation, value) = patch;
|
var usernmae = patch.Username;
|
||||||
|
var operation = GetOperation(nameOf(patch.Username);
|
||||||
|
|
||||||
Console.WriteLine($"Operation: {operation}, Value: {value}");
|
Console.WriteLine($"Operation: {operation}, Value: {value}");
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,25 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.Reflection;
|
||||||
using System.Reflection;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
using MaksIT.Core.Webapi.Models;
|
using MaksIT.Core.Webapi.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace MaksIT.Core.Abstractions.Webapi;
|
namespace MaksIT.Core.Abstractions.Webapi;
|
||||||
|
|
||||||
public abstract class PatchRequestModelBase : RequestModelBase, IValidatableObject {
|
public abstract class PatchRequestModelBase : RequestModelBase {
|
||||||
|
|
||||||
|
public Dictionary<string, PatchOperation> Operations = new Dictionary<string, PatchOperation>();
|
||||||
|
|
||||||
private bool HasNonNullPatchField => GetType()
|
private bool HasNonNullPatchField => GetType()
|
||||||
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||||
.Where(prop => prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(PatchField<>))
|
.Where(prop => prop.Name != nameof(Operations))
|
||||||
.Any(prop => prop.GetValue(this) != null);
|
.Any(prop => prop.GetValue(this) != null);
|
||||||
|
|
||||||
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
|
public PatchOperation GetOperation(string propertyName) {
|
||||||
|
return Operations[propertyName];
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
|
||||||
if (!HasNonNullPatchField) {
|
if (!HasNonNullPatchField) {
|
||||||
yield return new ValidationResult("At least one patch field must be provided", new string[] { "PatchField" });
|
yield return new ValidationResult("At least one patch field must be provided", new string[] { "PatchField" });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MaksIT.Core.Abstractions.Webapi;
|
namespace MaksIT.Core.Abstractions.Webapi;
|
||||||
public abstract class RequestModelBase {
|
public abstract class RequestModelBase : IValidatableObject {
|
||||||
|
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
|
||||||
|
return Enumerable.Empty<ValidationResult>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<!-- NuGet package metadata -->
|
<!-- NuGet package metadata -->
|
||||||
<PackageId>MaksIT.Core</PackageId>
|
<PackageId>MaksIT.Core</PackageId>
|
||||||
<Version>1.2.2</Version>
|
<Version>1.2.3</Version>
|
||||||
<Authors>Maksym Sadovnychyy</Authors>
|
<Authors>Maksym Sadovnychyy</Authors>
|
||||||
<Company>MAKS-IT</Company>
|
<Company>MAKS-IT</Company>
|
||||||
<Product>MaksIT.Core</Product>
|
<Product>MaksIT.Core</Product>
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
namespace MaksIT.Core.Webapi.Models;
|
|
||||||
|
|
||||||
public class PatchField<T> {
|
|
||||||
public PatchOperation Operation { get; set; }
|
|
||||||
public T? Value { get; set; }
|
|
||||||
|
|
||||||
public void Deconstruct(out PatchOperation operation, out T? value) {
|
|
||||||
operation = Operation;
|
|
||||||
value = Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user