Class ValidationArgValue
- Namespace
- Trellis
- Assembly
- Trellis.Core.dll
The value of a single entry in the Args carried by a FieldViolation or
RuleViolation.
[JsonConverter(typeof(ValidationArgValueJsonConverter))]
public abstract record ValidationArgValue : IEquatable<ValidationArgValue>
- Inheritance
-
ValidationArgValue
- Implements
- Derived
- Inherited Members
- Extension Methods
Examples
ValidationArgs.Of("maxLength", 50) // {"maxLength": 50}
ValidationArgs.Of("min", 0, "max", 255) // {"min": 0, "max": 255}
ValidationArgs.Of("allowed", ValidationArgValue.ListOf("red", "green"))
Remarks
This is a closed union — ValidationArgValue.Text, ValidationArgValue.Number, ValidationArgValue.Bool, or ValidationArgValue.List — and the constructor is private so it stays closed. A client can therefore switch over it exhaustively, and the JSON shape of an arg is knowable from the type alone rather than from whatever a producer happened to pass.
The cases are JSON's self-describing values: its three scalars, plus a list of them. JSON's
other two constructs are deliberately absent. null would give a dictionary two spellings
of the same thing, since an arg with no value is an arg that is simply not there. An object
would mean a client needs a schema per reason code to know what it is looking at, which gives up
the property that makes this union worth having — that the shape follows from the type — and
turns args into an open-ended payload, which is a poor thing to echo back to a caller.
The predecessor of this type was string, which forced every operand onto the wire
quoted: a length bound arrived as "maxLength": "50", and a client that wanted to compare
it against a length had to parse it back out, guessing at the format. Modelling the number as a
number removes the guess — "maxLength": 50 — while keeping the property that made
string attractive in the first place, which is that no producer-side culture can
leak into the payload. ValidationArgValue.Number holds a decimal and is written by
System.Text.Json invariantly, so a German server and an American one emit the same
bytes.
Args are still operands, not an echo of the caller's input. Never put the rejected value itself in here — a rejected password or token would then be reflected back in an error response and into whatever logs that response.
Methods
ListFrom(IEnumerable<ValidationArgValue>)
Builds a ValidationArgValue.List from a sequence.
public static ValidationArgValue ListFrom(IEnumerable<ValidationArgValue> items)
Parameters
itemsIEnumerable<ValidationArgValue>The list members, in order.
Returns
ListOf(params ValidationArgValue[])
Builds a ValidationArgValue.List from the supplied items.
public static ValidationArgValue ListOf(params ValidationArgValue[] items)
Parameters
itemsValidationArgValue[]The list members, in order. May be empty.
Returns
Operators
implicit operator ValidationArgValue(bool)
Wraps a boolean as ValidationArgValue.Bool.
public static implicit operator ValidationArgValue(bool value)
Parameters
valueboolThe flag.
Returns
implicit operator ValidationArgValue(decimal)
Wraps a decimal as ValidationArgValue.Number.
public static implicit operator ValidationArgValue(decimal value)
Parameters
valuedecimalThe number.
Returns
implicit operator ValidationArgValue(int)
Wraps an integer as ValidationArgValue.Number.
public static implicit operator ValidationArgValue(int value)
Parameters
valueintThe number.
Returns
implicit operator ValidationArgValue(long)
Wraps a long as ValidationArgValue.Number.
public static implicit operator ValidationArgValue(long value)
Parameters
valuelongThe number.
Returns
implicit operator ValidationArgValue(string)
Wraps a string as ValidationArgValue.Text.
public static implicit operator ValidationArgValue(string value)
Parameters
valuestringThe text.