PTrampert.SimplePatch.Schema 1.2.1

dotnet add package PTrampert.SimplePatch.Schema --version 1.2.1
                    
NuGet\Install-Package PTrampert.SimplePatch.Schema -Version 1.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PTrampert.SimplePatch.Schema" Version="1.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PTrampert.SimplePatch.Schema" Version="1.2.1" />
                    
Directory.Packages.props
<PackageReference Include="PTrampert.SimplePatch.Schema" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PTrampert.SimplePatch.Schema --version 1.2.1
                    
#r "nuget: PTrampert.SimplePatch.Schema, 1.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PTrampert.SimplePatch.Schema@1.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PTrampert.SimplePatch.Schema&version=1.2.1
                    
Install as a Cake Addin
#tool nuget:?package=PTrampert.SimplePatch.Schema&version=1.2.1
                    
Install as a Cake Tool

PTrampert.SimplePatch

Library supporting simple patch objects in .NET.

Overview

PTrampert.SimplePatch is a C# library designed to facilitate the handling of flat PATCH objects in .NET web applications. With this library, you can easily distinguish between properties that are omitted from a PATCH request and those explicitly set to null or a value.

This is especially useful when you want to update only specific properties of an object, leaving others unchanged. For example, if you send a PATCH request like:

{
  "name": "New Name"
}

and your object contains additional properties besides name, PTrampert.SimplePatch makes it easy to ensure that only name is updated, and all other properties remain untouched.

Features

  • Supports "Optional" types for PATCH operations.
  • Dynamically generates implementations of IPatchObject for your write models.
  • Preserves validation attributes on properties, allowing for validation of PATCH requests.
  • Handles complex types with custom JSON converters.
  • Documents PATCH routes properly in OpenAPI, via optional Swashbuckle and Microsoft.AspNetCore.OpenApi integration packages.

Getting Started

A full sample project is available in the PTrampert.SimplePatch.Samples

  • Install the library via NuGet:
dotnet add package PTrampert.SimplePatch
  • Create your write model class
public record PersonWriteModel
{
    // For PATCH requests, Required will only be enforced if the property is present in the request body.
    [Required]
    [StringLength(255, MinimumLength = 3)]
    public required string Name { get; init; }
    
    public DateTime DateOfBirth { get; init; }
    
    // Validation attributes can be used to enforce rules on the email field.
    [EmailAddress]
    public string? Email { get; init; }
    
    // Using a custom JSON converter to handle phone number serialization and deserialization
    [JsonConverter(typeof(PhoneNumberJsonConverter))]
    public PhoneNumber? PhoneNumber { get; init; }
}
  • Use IPatchObject<PersonWriteModel> to create an optional object for PATCH operations:
    [HttpPatch("{id:int}")]
    public ActionResult<PersonReadModel> PatchPerson(
        int id,
        // PTrampert.SimplePatch automatically generates an implementation of IPatchObject<PersonWriteModel>
        [FromBody] IPatchObject<PersonWriteModel> patchObject)
    {
        // Validation is preserved on the patch object, so we can check ModelState
        if (!ModelState.IsValid)
            return BadRequest(ModelState);
        
        var existingPerson = _db.GetPersonById(id);
        if (existingPerson == null)
            return NotFound();
        
        var patchedPerson = patchObject.Patch(existingPerson);
        var updatedPerson = _db.UpdatePerson(id, patchedPerson);
        
        return updatedPerson!;
    }

This will allow you to make the following HTTP request to update only the specified properties of Person (in this example, only the 'name' property).

PATCH /person/1 HTTP/1.1
Content-Type: application/json
Content-Length: 24

{
  "name": "New Name"
}

OpenAPI

Out of the box, an OpenAPI generator describes a [FromBody] IPatchObject<T> parameter from the interface, which has no properties. The request body ends up documented as an empty object — useless to a reader, and strict enough to reject every legal PATCH:

"PersonWriteModelIPatchObject": { "type": "object", "additionalProperties": false }

Install the integration package for your generator to document the patched model's schema instead, with every property optional.

Swashbuckle

dotnet add package PTrampert.SimplePatch.Swashbuckle
builder.Services.AddSwaggerGen(options => options.AddSimplePatchSchemas());

Microsoft.AspNetCore.OpenApi (.NET 10+)

dotnet add package PTrampert.SimplePatch.OpenApi
builder.Services.AddOpenApi(options => options.AddSimplePatchSchemas());

Either way the PATCH body is now described with the model's own properties, validation constraints and converters, and nothing marked required:

"PersonWriteModelIPatchObject": {
  "type": "object",
  "properties": {
    "name":        { "maxLength": 255, "minLength": 3, "type": "string" },
    "dateOfBirth": { "type": "string", "format": "date-time" },
    "email":       { "type": "string", "format": "email", "nullable": true },
    "phoneNumber": { "$ref": "#/components/schemas/PhoneNumber" }
  },
  "additionalProperties": false,
  "description": "Partial update of PersonWriteModel. Omitted properties are left unchanged."
}

Because the patch schema is derived from the model's own schema, anything you already do to tune that model — a MapType, a schema filter, XML comments — applies to the PATCH body too, and the two can never describe different shapes.

Setting an example

Swagger UI builds its example from the schema's properties and ignores required, so by default the PATCH example lists every property — which reads as "send all of these", and is what Try it out will submit. Supply an example to show the partial-update semantics instead:

builder.Services.AddSwaggerGen(options => options.AddSimplePatchSchemas(patch =>
{
    patch.Example = _ => new JsonObject { ["name"] = "New Name" };
}));

Other options

AddSimplePatchSchemas takes a SimplePatchSchemaOptions:

Option Default Effect
Example null Example body for the patch schema. See above.
SchemaId null Names the patch schema component. t => t.Name + "Patch" gives PersonWriteModelPatch instead of PersonWriteModelIPatchObject.
DescriptionFormat "Partial update of {0}. Omitted properties are left unchanged." The patch schema's description. Null leaves it alone.
ClearRequired true Drops required, which is what makes the body a partial update.
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on PTrampert.SimplePatch.Schema:

Package Downloads
PTrampert.SimplePatch.OpenApi

Microsoft.AspNetCore.OpenApi integration for PTrampert.SimplePatch. Documents routes taking an IPatchObject<T> with the patched model's schema instead of an empty object.

PTrampert.SimplePatch.Swashbuckle

Swashbuckle integration for PTrampert.SimplePatch. Documents routes taking an IPatchObject<T> with the patched model's schema instead of an empty object.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.1 108 9/12/2026
1.2.0 112 9/12/2026