Class ValueObjectJsonPatchExtensions
Namespace: AdCodicem.ValueObjects.AspNetCore.NewtonsoftJson
Assembly: AdCodicem.ValueObjects.AspNetCore.NewtonsoftJson.dll
Applies JSON Patch documents whose values each value object reads through its rules.
public static class ValueObjectJsonPatchExtensions
Inheritance
object ← ValueObjectJsonPatchExtensions
Inherited Members
object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.MemberwiseClone(), object.ReferenceEquals(object?, object?), object.ToString()
Remarks
MVC reads a ApplyTo then converts it by writing it to text and
reading it back under settings of its own, and reports any refusal in its own words, which quote the value and name
no rule; MVC's ApplyTo(objectToApplyTo, ModelState) puts every error under the type name of the object. These
methods apply the same document through the value objects' rules, with their messages and codes.
add, replace and test read a value into a value object member, list element or dictionary value
as the document holds it, a string, a number, a boolean, a null or a JToken, never written to text
and read again: through AddValueObjectsNewtonsoftJson() is in place. A refused value is reported with the
converter's message, which names the type and the rule and never the value, and the code of the rule; a null
read into a value object that cannot be null is copy or move,
is kept as it is, but for a default instance its type refuses, which no writer writes either.
A dictionary keyed by a value object reads each key through the value object's rules, from its text in the invariant culture, as a route value is read: a refused key reads "The key is not a valid CountryCode: …", with its code.
A test of a value object compares through the value object's equality, so 12.5 matches a stored
12.50, an instant matches the same instant at another offset, and a closed set compared ignoring case matches
another case. One that does not match names neither value, and carries no code.
A value object member that cannot be null cannot be removed, which JSON Patch would do by setting
it to its default instance: remove is refused with move from it, which then adds nothing at its target. Declare the member T? to remove it. A move
to the location it comes from changes nothing.
A member of another type, a value object inside an object value, which JSON Patch converts as a whole, and every
error no value explains are JSON Patch's, with its messages, which may quote the value. An operation that names no
path, or a copy or a move that names no from, is an error, where JSON Patch throws, and
so is -, the end of a list, where it holds no element to read, remove, replace or test.
Every operation is applied in turn, after one that failed too, as MVC's ApplyTo does: on
false the object is partly patched, and is not to be saved. JSON Patch stops at an operation it
cannot read, an unknown op or a path with a bad escape, which is reported. Nothing is thrown for what the client
sent; the messages are English, as those of a body Newtonsoft.Json reads.
Methods
TryApplyTo<TModel>(JsonPatchDocument<TModel>, TModel, ModelStateDictionary, HttpContext, string?)
Applies the operations and records each error in the model state under the operation's path, with the code of the rule a value broke for the problem details.
public static bool TryApplyTo<TModel>(this JsonPatchDocument<TModel> patchDocument, TModel objectToApplyTo, ModelStateDictionary modelState, HttpContext httpContext, string? prefix = null) where TModel : class
Parameters
patchDocument JsonPatchDocument<TModel>
The document, as MVC read it.
objectToApplyTo TModel
The object it patches.
modelState ModelStateDictionary
Where each error is recorded.
httpContext HttpContext
The request the codes are recorded on, for AddValueObjectProblemDetails() or
prefix string?
Put before the path of each error's key, or null.
Returns
true when every operation applied.
Type Parameters
TModel
The type the document patches.
Remarks
Each error is keyed by the operation's path, as the client sent it, /quantity or /ibans/-,
after prefix, joined with no separator since the path starts with /: patch gives
patch/quantity. A copy or a move refused at its source, a from JSON Patch cannot read
included, is keyed by its from, and an operation that names no path by the prefix alone. A key
refused more than once keeps every message and its first code, as
The codes reach the response AddValueObjectProblemDetails() adds them, when the action answers with it: the automatic 400 runs before
the action, and never sees the errors recorded here. An action answering with ValidationProblem() goes
through MVC's ProblemDetailsFactory instead, and passes them itself, in its extensions:
Exceptions
patchDocument, objectToApplyTo, modelState or
httpContext is null.
TryApplyTo<TModel>(JsonPatchDocument<TModel>, TModel, Action<JsonPatchError, string?>)
Applies the operations and hands each error the code of the rule a value broke, or null.
public static bool TryApplyTo<TModel>(this JsonPatchDocument<TModel> patchDocument, TModel objectToApplyTo, Action<JsonPatchError, string?> logError) where TModel : class
Parameters
patchDocument JsonPatchDocument<TModel>
The document.
objectToApplyTo TModel
The object it patches.
logError Action<JsonPatchError, string?>
Called with each error, and the code of the rule a value broke, or null for an error no rule explains.
Returns
true when every operation applied.
Type Parameters
TModel
The type the document patches.
Remarks
The error's new JsonSerializerSettings().AddValueObjects(): under Newtonsoft.Json's defaults, a string
that looks like a date and the digits of a
Exceptions
patchDocument, objectToApplyTo or logError is
null.