From eaa610a8533410e6f630f7353202659188a2eb3b Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sat, 14 Dec 2024 17:54:06 +0100 Subject: [PATCH] (feature): simplify patch request fields management for frontend validation like zod --- README.md | 30 +++++++------------ .../Webapi/PatchRequestModelBase.cs | 18 +++++++---- .../Abstractions/Webapi/RequestModelBase.cs | 6 +++- src/MaksIT.Core/MaksIT.Core.csproj | 2 +- src/MaksIT.Core/Webapi/Models/PatchField.cs | 12 -------- 5 files changed, 29 insertions(+), 39 deletions(-) delete mode 100644 src/MaksIT.Core/Webapi/Models/PatchField.cs diff --git a/README.md b/README.md index af6ad3f..30e1872 100644 --- a/README.md +++ b/README.md @@ -1945,22 +1945,7 @@ var response = new PagedResponse(users, totalCount: 100, pageNumber: 1, pa --- -#### **3. `PatchField`** - -##### Summary -Represents a patch operation on a specific field or value, used for partial updates in Web APIs. - -##### Usage -```csharp -var patchField = new PatchField { - Operation = PatchOperation.Replace, - Value = "New Value" -}; -``` - ---- - -#### **4. `PatchOperation`** +#### **3. `PatchOperation`** ##### Summary 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 ```csharp -var patch = new PatchField { - Operation = PatchOperation.Replace, - Value = "Updated Name" +var patch = new SomePatchRequestModel { + Username = "Updated Name" + + Operations = new Dictionary { + { "Username", PartchOperation.Replace } + } }; // Deconstruct the patch field -var (operation, value) = patch; +var usernmae = patch.Username; +var operation = GetOperation(nameOf(patch.Username); + Console.WriteLine($"Operation: {operation}, Value: {value}"); ``` diff --git a/src/MaksIT.Core/Abstractions/Webapi/PatchRequestModelBase.cs b/src/MaksIT.Core/Abstractions/Webapi/PatchRequestModelBase.cs index 458094b..1ff17ca 100644 --- a/src/MaksIT.Core/Abstractions/Webapi/PatchRequestModelBase.cs +++ b/src/MaksIT.Core/Abstractions/Webapi/PatchRequestModelBase.cs @@ -1,17 +1,25 @@ -using System.ComponentModel.DataAnnotations; -using System.Reflection; +using System.Reflection; +using System.ComponentModel.DataAnnotations; + using MaksIT.Core.Webapi.Models; namespace MaksIT.Core.Abstractions.Webapi; -public abstract class PatchRequestModelBase : RequestModelBase, IValidatableObject { +public abstract class PatchRequestModelBase : RequestModelBase { + + public Dictionary Operations = new Dictionary(); + private bool HasNonNullPatchField => GetType() .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); - public virtual IEnumerable Validate(ValidationContext validationContext) { + public PatchOperation GetOperation(string propertyName) { + return Operations[propertyName]; + } + + public override IEnumerable Validate(ValidationContext validationContext) { if (!HasNonNullPatchField) { yield return new ValidationResult("At least one patch field must be provided", new string[] { "PatchField" }); } diff --git a/src/MaksIT.Core/Abstractions/Webapi/RequestModelBase.cs b/src/MaksIT.Core/Abstractions/Webapi/RequestModelBase.cs index c195bd5..61b2329 100644 --- a/src/MaksIT.Core/Abstractions/Webapi/RequestModelBase.cs +++ b/src/MaksIT.Core/Abstractions/Webapi/RequestModelBase.cs @@ -1,9 +1,13 @@ using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MaksIT.Core.Abstractions.Webapi; -public abstract class RequestModelBase { +public abstract class RequestModelBase : IValidatableObject { + public virtual IEnumerable Validate(ValidationContext validationContext) { + return Enumerable.Empty(); + } } diff --git a/src/MaksIT.Core/MaksIT.Core.csproj b/src/MaksIT.Core/MaksIT.Core.csproj index f3bf53f..64ea5c5 100644 --- a/src/MaksIT.Core/MaksIT.Core.csproj +++ b/src/MaksIT.Core/MaksIT.Core.csproj @@ -8,7 +8,7 @@ MaksIT.Core - 1.2.2 + 1.2.3 Maksym Sadovnychyy MAKS-IT MaksIT.Core diff --git a/src/MaksIT.Core/Webapi/Models/PatchField.cs b/src/MaksIT.Core/Webapi/Models/PatchField.cs deleted file mode 100644 index 3518a4f..0000000 --- a/src/MaksIT.Core/Webapi/Models/PatchField.cs +++ /dev/null @@ -1,12 +0,0 @@ - -namespace MaksIT.Core.Webapi.Models; - -public class PatchField { - public PatchOperation Operation { get; set; } - public T? Value { get; set; } - - public void Deconstruct(out PatchOperation operation, out T? value) { - operation = Operation; - value = Value; - } -}