Skip to main content
Version: 0.3.x (0.3.0)

Class ValueObjectMvcExtensions

Namespace: AdCodicem.ValueObjects.AspNetCore
Assembly: AdCodicem.ValueObjects.AspNetCore.dll

Wires value object support into an ASP.NET Core application.

public static class ValueObjectMvcExtensions

Inheritance​

object ← ValueObjectMvcExtensions

Inherited Members​

object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.MemberwiseClone(), object.ReferenceEquals(object?, object?), object.ToString()

Methods​

AddValueObjectProblemDetails(ApiBehaviorOptions)​

Adds the stable error codes of the rejected value objects to the automatic 400 response.

public static ApiBehaviorOptions AddValueObjectProblemDetails(this ApiBehaviorOptions options)

Parameters​

options ApiBehaviorOptions

API behaviour options.

Returns​

ApiBehaviorOptions

The same options, so calls can be chained.

Remarks​

The framework's own ValidationProblemDetails response is kept as is, with an errorCodes extension added next to errors: the human-readable messages stay where clients expect them, and a client that wants to branch on a rule now has something stable to branch on.

AddValueObjects(MvcOptions)​

Binds value objects from the underlying value everywhere MVC reads text.

public static MvcOptions AddValueObjects(this MvcOptions options)

Parameters​

options MvcOptions

MVC options.

Returns​

MvcOptions

The same options, so calls can be chained.

Remarks​

The provider is inserted first so that it wins over the built-in simple-type and complex-type binders, which would otherwise try to bind a value object as an object with a Value property. It declines a greedy binding source, which MVC's own providers bind: a header, through this binder again, the body, through the input formatter, the services, and a binder named by [ModelBinder(typeof(…))].

This adds the binder alone. also configures the JSON options, and records the code of a value refused inside a request body.

The options hold one provider: calling this again, or , keeps the provider where the first call put it, and the last configuration of its messages wins.

AddValueObjects(MvcOptions, Action<ValueObjectMessageOptions>)​

Binds value objects from the underlying value everywhere MVC reads text, giving a refusal the message the application's resource holds for its code.

public static MvcOptions AddValueObjects(this MvcOptions options, Action<ValueObjectMessageOptions> configure)

Parameters​

options MvcOptions

MVC options.

configure Action<ValueObjectMessageOptions>

Names the resource the messages are read from, through .

Returns​

MvcOptions

The same options, so calls can be chained.

Remarks​

The binder is added as adds it, and a value it refuses in a route, query, header or form value is reported with the message the resource holds under the key of the rule's code, ValueObject.value_object.too_short, looked up after ValueObject.value_object.out_of_range.minimum or .maximum for a type declaring one bound alone. It is formatted with the display name of the member as {0}, and the arguments the type's rules supply from {1}: a length, both bounds, the known values. The code under errorCodes is the same in every language, and a key the resource lacks keeps the English message. Blank text keeps the framework's message, which MVC's own message provider localises.

The resource is read through the request's IStringLocalizerFactory: register builder.Services.AddLocalization(), without which a refusal throws an naming it, and app.UseRequestLocalization(), so that the request chooses the culture. The current UI culture chooses the template and the current culture formats the arguments. A template quoting an argument its code does not supply throws its , which is not caught.

A request body is read by the input formatter, which puts in place: on the options alone, a body keeps its English message.

Exceptions​

ArgumentNullException

options or configure is null.

AddValueObjects(IMvcBuilder)​

Registers value object model binding and JSON serialization on an MVC builder.

public static IMvcBuilder AddValueObjects(this IMvcBuilder builder)

Parameters​

builder IMvcBuilder

MVC builder.

Returns​

IMvcBuilder

The same builder, so calls can be chained.

Remarks​

It also puts a formatter of its own in place of MVC's System.Text.Json input formatter, at its index: one deriving from it, which reads with the very serializer options the framework's formatter read with, and records the code of a value object a request body refuses, so that puts it in the response under the JSON path, as it puts the code of a route or query value under the parameter. The model state keeps the messages it keeps without it, whatever says, unless messages are configured, through or on the options, which replace the message of the exception with the resource's under that option, its default. A change made to the JSON options later on reaches it as it reaches the framework's. A System.Text.Json formatter the application built with options of its own, or derived, is left as it is, and records no code.

The swap is a post-configuration of . Removing the framework's formatter with InputFormatters.RemoveType<SystemTextJsonInputFormatter>() still works in AddMvcOptions, in Configure<MvcOptions> or in a post-configuration registered before this call; in one registered after it, that finds this formatter in its place, which is not of that exact type: remove there every formatter that is a , derived included.

Once Newtonsoft.Json reads the body, through AddNewtonsoftJson(), there is no such formatter to replace, and a body records no code; AddValueObjectsNewtonsoftJson(), from AdCodicem.ValueObjects.AspNetCore.NewtonsoftJson, replaces Newtonsoft.Json's formatter instead.

AddValueObjects(IMvcBuilder, Action<ValueObjectMessageOptions>)​

Registers value object model binding and JSON serialization on an MVC builder, giving a refusal, in a route, query, header or form value or in a JSON body, the message the application's resource holds for its code.

public static IMvcBuilder AddValueObjects(this IMvcBuilder builder, Action<ValueObjectMessageOptions> configure)

Parameters​

builder IMvcBuilder

MVC builder.

configure Action<ValueObjectMessageOptions>

Names the resource the messages are read from, through .

Returns​

IMvcBuilder

The same builder, so calls can be chained.

Remarks​

Everything registers is registered, and the messages are configured as configures them, which says how they are looked up. The input formatter reads them too: a value object a JSON body refuses is reported under its JSON path with the message the resource holds for the code, quoting the name of the value object as {0}, since the path may hold a refused dictionary key, the refused value itself. A type the registry cannot describe, such as AnyEntityId, has the key of the code alone and no argument.

A body's message is translated only where MVC answers with it, under , its default; turned off, every error of a body is answered "The input was not valid.", which MVC's message provider holds. A body read by Newtonsoft.Json, through AdCodicem.ValueObjects.AspNetCore.NewtonsoftJson, keeps its English message.

Exceptions​

ArgumentNullException

builder or configure is null.