Nextended.ResponseFilters — API reference
The complete public surface of Nextended.ResponseFilters, generated from the compiled assembly.
Generated
This page is generated by tools/ApiRef from the compiled assembly — it includes members with no XML comment and therefore cannot drift from the code. Do not edit by hand.
Nextended.ResponseFilters
AsyncPredicate<T>
delegate
Async predicate used by rule builders.
Constructors
AsyncPredicate(object object, IntPtr method)
Methods
BeginInvoke(T instance, IResponseFilterContext context, AsyncCallback callback, object object) : IAsyncResultEndInvoke(IAsyncResult result) : ValueTask<bool>Invoke(T instance, IResponseFilterContext context) : ValueTask<bool>
FilterExceptionBehavior
enum
How ExceptionBehavior shapes the pipeline's response to thrown filter rules.
Values
LogAndContinue
Catch exceptions thrown by filter rules, log them viaILogger<ResponseFilterPipeline>, and continue with remaining filters. The response is returned partially filtered. Use only in pipelines where filter robustness matters more than visibility (e.g. a public CMS that must never 500).Rethrow
Let exceptions propagate (default). This is the right choice for almost every app — a filter throwing aBusinessException,UserFriendlyException, or any other domain error should reach the framework's global exception handler unchanged.value__
InlineFilter<T>
class
Concrete ResponseFilter1used internally byForEach` sub-filters, also exposed for ad-hoc filters configured at runtime (e.g. in tests).
Constructors
InlineFilter()
Methods
AddProperty(string name) : AddPropertyBuilder<T>Apply(Action<T, IResponseFilterContext> action) : ApplyBuilder<T>ApplyAsync(Func<T, IResponseFilterContext, Task> action) : ApplyBuilder<T>Clear<TProp>(Expression<Func<T, TProp>> selector) : ClearBuilder<T>ForEach<TItem>(Expression<Func<T, IEnumerable<TItem>>> selector, Action<InlineFilter<TItem>> configure) : ResponseFilter<T>Hash(Expression<Func<T, string>> selector) : HashBuilder<T>KeepOnly<TItem>(Expression<Func<T, IEnumerable<TItem>>> selector) : KeepOnlyBuilder<T, TItem>Mask(Expression<Func<T, string>> selector) : MaskBuilder<T>Nullify<TProp>(Expression<Func<T, TProp>>[] selectors) : NullifyBuilder<T>Properties(Expression<Func<T, object>>[] selectors) : PropertySetBuilder<T>PropertiesWhere(Func<PropertyInfo, bool> predicate) : PropertySetBuilder<T>Remove(Expression<Func<T, object>>[] selectors) : RemoveBuilder<T>RemoveItems<TItem>(Expression<Func<T, IEnumerable<TItem>>> selector) : RemoveItemsBuilder<T, TItem>Rename<TProp>(Expression<Func<T, TProp>> selector) : RenameBuilder<T>Replace<TProp>(Expression<Func<T, TProp>> selector) : ReplaceBuilder<T, TProp>Round<TNum>(Expression<Func<T, TNum>> selector) : RoundBuilder<T>Round<TNum>(Expression<Func<T, TNum?>> selector) : RoundBuilder<T>SetToDefault(Expression<Func<T, object>>[] selectors) : SetToDefaultBuilder<T>SetValue<TProp>(Expression<Func<T, TProp>> selector) : SetValueBuilder<T, TProp>Take<TItem>(Expression<Func<T, IEnumerable<TItem>>> selector) : TakeBuilder<T, TItem>Transform<TProp>(Expression<Func<T, TProp>> selector) : TransformBuilder<T, TProp>TransformKey<TProp>(Expression<Func<T, TProp>> selector) : TransformKeyBuilder<T>TransformKeys() : TransformKeyBuilder<T>Truncate(Expression<Func<T, string>> selector) : TruncateBuilder<T>
IResponseFilter
interface
Non-generic marker for filters keyed by TargetType. Implemented by ResponseFilter1`; consumers typically don't implement this directly.
Methods
ApplyAsync(object instance, IResponseFilterContext context) : ValueTask
Apply all configured rules toinstance. Implementations MUST tolerateinstancebeing of a derived type or null-safe assignable.
Properties
TargetType : Type { get; }
The exact DTO type this filter applies to (no inheritance walking).
IResponseFilterContext
interface
Per-pipeline context handed to every predicate and rule. Hosts the service provider, cancellation, and a scratch bag for memoizing async values (e.g. permission checks) so repeated predicates within the same response don't re-fetch.
Properties
CancellationToken : CancellationToken { get; }
Cancellation token bound to the host request/scope.Items : IDictionary<string, object> { get; }
Free-form bag for transporting arbitrary state between rules of the same pipeline run (e.g. an authenticated user object, a tenant id, a cached permission map). Not thread-safe; rules are applied sequentially per object.Services : IServiceProvider { get; }
DI container scope for the current request.StructuralEdits : StructuralEditBook { get; }
Ledger of structural edits (remove / rename / key-transform / add) recorded by structural rules. A POCO can't drop or rename a property at runtime, so these are collected here and replayed against the serialized JSON tree by the serialization layer (e.g. the ASP.NET Core adapter).
IResponseFilterRule<T>
interface
Single rule attached to a ResponseFilter1`.
Methods
ApplyAsync(T instance, IResponseFilterContext context) : ValueTask
ResponseFilter<T>
abstract class
Base class for declarative response filters. Inherit and configure rules in the constructor via the protected fluent builders (Nullify``1, Replace``1, Transform``1, ForEach``1).
Methods
ApplyAsync(T instance, IResponseFilterContext context) : ValueTaskApplyAsync(object instance, IResponseFilterContext context) : ValueTask
Properties
TargetType : Type { get; }
ResponseFilterContext
class
Default IResponseFilterContext.
Constructors
ResponseFilterContext(IServiceProvider services, CancellationToken cancellationToken = null)
Properties
CancellationToken : CancellationToken { get; }Items : IDictionary<string, object> { get; }Services : IServiceProvider { get; }StructuralEdits : StructuralEditBook { get; }
ResponseFilterOptions
class
Pipeline-wide options. Configure once at registration time via services.AddResponseFilters(..., configure: o => { … }).
Constructors
ResponseFilterOptions()
Properties
ExceptionBehavior : FilterExceptionBehavior { get; set; }
How the pipeline reacts when a filter rule throws. Default:Rethrow— surface bugs early.SkipResponseType : Func<Type, bool> { get; set; }
Optional opt-out predicate. When set and returnstruefor the response root type, the pipeline is skipped for that response (evaluated beforeSkipUnaffectedResponses).SkipUnaffectedResponses : bool { get; set; }
Whentrue(default), the pipeline performs a one-time reachability analysis per response root type. If no registered filter's target type is reachable in the type graph, the entire pipeline is skipped — no reflection, no graph walk.
StructuralEdit
class
A structural change to apply to an object's serialized representation. Unlike value mutators (Nullify, Mask, …) which mutate the DTO in place, structural edits cannot be expressed on a strongly-typed POCO — a property can't be removed or its key renamed at runtime. They are therefore recorded per-instance in the StructuralEditBook and applied at serialization time (see JsonStructuralTransformer).
Methods
AddProperty(string name, object value) : StructuralEdit
Inject a new keynamewith the givenvalue.Remove(string propertyName) : StructuralEdit
DroppropertyNamefrom the output.Rename(string propertyName, string newName) : StructuralEdit
RenamepropertyName's serialized key tonewName.TransformKey(string propertyName, Func<string, string> keyTransform) : StructuralEdit
Properties
KeyTransform : Func<string, string> { get; }
ForTransformKey: maps the current serialized key to the new one.Kind : StructuralEditKind { get; }
What this edit does.NewName : string { get; }
ForRenamethe new serialized key; forAddPropertythe key of the injected property.PropertyName : string { get; }
The CLR property name the edit targets (forRemove,Rename,TransformKey). The transformer resolves this to the actual serialized JSON key.nullforAddProperty.Value : object { get; }
ForAddProperty: the already-computed value to serialize.
StructuralEditBook
class
Per-pipeline-run ledger of StructuralEdits, keyed by the object instance the edit applies to (reference identity). Structural rules record into it while the pipeline walks the graph; the serialization layer replays it against the produced JSON tree.
Constructors
StructuralEditBook()
Methods
ForOwner(object owner) : IReadOnlyList<StructuralEdit>
The edits recorded forowner, ornullwhen there are none.Record(object owner, StructuralEdit edit) : void
Record an edit againstowner. No-op whenowneris null.
Properties
HasAny : bool { get; }
True when at least one edit has been recorded — lets the host skip the JSON transform entirely.
StructuralEditKind
enum
The kind of structural change a StructuralEdit describes.
Values
AddProperty
Inject an additional key/value pair that does not exist on the CLR type.Remove
Drop a property entirely so it no longer appears in the serialized output.Rename
Rename a property's serialized key to a fixed name.TransformKey
Transform a property's serialized key through a function.value__
SyncPredicate<T>
delegate
Sync predicate used by rule builders.
Constructors
SyncPredicate(object object, IntPtr method)
Methods
BeginInvoke(T instance, IResponseFilterContext context, AsyncCallback callback, object object) : IAsyncResultEndInvoke(IAsyncResult result) : boolInvoke(T instance, IResponseFilterContext context) : bool
Nextended.ResponseFilters.Builders
AddPropertyBuilder<T>
class
Two-step builder that injects an extra key into the serialized output — a key that does not exist on the CLR type. First specify the value via From(...)/WithValue(...), then close with the predicate vocabulary.
Methods
From(Func<T, IResponseFilterContext, object> valueFactory) : AddPropertyTerminal<T>From(Func<T, object> valueFactory) : AddPropertyTerminal<T>WithValue(object value) : AddPropertyTerminal<T>
Inject a constant value.
AddPropertyTerminal<T>
class
Terminal phase of an AddProperty rule — applies the predicate vocabulary.
ApplyBuilder<T>
class
Builder for the catch-all Apply rule: runs an arbitrary Action on the instance when the predicate matches.
ClearBuilder<T>
class
Sets a property to its "empty" state: String → Empty``IList with IsReadOnly = false → in-place .Clear()Arrays → new zero-length array of the element typeAnything else → null (logged warning at pipeline level if assignment fails)
HashBuilder<T>
class
Builder that replaces a String property with a hash of its current value. Default algorithm is SHA-256, emitted as lowercase hex.
Methods
AsMd5() : HashBuilder<T>AsSha1() : HashBuilder<T>AsSha256() : HashBuilder<T>AsSha512() : HashBuilder<T>Using(Func<string, string> hasher) : HashBuilder<T>
IRuleBuilder<T>
interface
Marker interface for every fluent rule builder produced by ResponseFilter1`.
Methods
When(AsyncPredicate<T> predicate) : ResponseFilter<T>
KeepOnlyBuilder<T, TItem>
class
Mirror of RemoveItemsBuilder2` with inverted semantics: items matching the predicate are kept; everything else is removed.
Methods
Where(AsyncPredicate<TItem> itemPredicate) : RemoveItemsTerminal<T, TItem>Where(Func<TItem, bool> itemPredicate) : RemoveItemsTerminal<T, TItem>Where(SyncPredicate<TItem> itemPredicate) : RemoveItemsTerminal<T, TItem>
MaskBuilder<T>
class
Builder for masking String properties.
Methods
KeepFirst(int count) : MaskBuilder<T>
Keep the firstcountcharacters visible. Capped at the string length.KeepLast(int count) : MaskBuilder<T>
Keep the lastcountcharacters visible. Capped at the string length.With(Char maskChar) : MaskBuilder<T>
Use a different mask character (default:'*').WithPattern(string pattern) : MaskBuilder<T>
Replace the whole value with a fixed pattern (ignores Keep* settings).
NullifyBuilder<T>
class
Builder for "set property to null when predicate matches" rules.
PropertySetBuilder<T>
class
Transposed entry point: select a set of properties first (by name via Properties, or by metadata via PropertiesWhere), then choose a type-agnostic operation to apply to all of them. Every operation returns the same builder the direct API returns, so the full terminal vocabulary (When/Unless/Always/WhenProperty) stays available.
Methods
Nullify() : NullifyBuilder<T>Remove() : RemoveBuilder<T>SetToDefault() : SetToDefaultBuilder<T>TransformKey() : TransformKeyBuilder<T>
RemoveBuilder<T>
class
Builder for "drop one or more properties from the serialized output when the predicate matches" rules.
RemoveItemsBuilder<T, TItem>
class
Two-step builder: first specify the per-item predicate via Where(...), then close with the standard predicate vocabulary (When/Unless/Always/...).
Methods
Where(AsyncPredicate<TItem> itemPredicate) : RemoveItemsTerminal<T, TItem>Where(Func<TItem, bool> itemPredicate) : RemoveItemsTerminal<T, TItem>Where(SyncPredicate<TItem> itemPredicate) : RemoveItemsTerminal<T, TItem>
RemoveItemsTerminal<T, TItem>
class
Terminal phase of a RemoveItems rule.
RenameBuilder<T>
class
Two-step builder: first specify the new key via To(...), then close with the standard predicate vocabulary (When/Unless/Always/...).
Methods
To(string newName) : RenameTerminal<T>
Rename the property's serialized key tonewName.
RenameTerminal<T>
class
Terminal phase of a Rename rule — applies the predicate vocabulary.
ReplaceBuilder<T, TProp>
class
Two-step builder: first specify the replacement value via With(...), then close with When(...)/Unless(...)/Always().
Methods
With(Func<T, IResponseFilterContext, TProp> valueFactory) : ReplaceTerminal<T, TProp>With(Func<T, TProp> valueFactory) : ReplaceTerminal<T, TProp>With(TProp value) : ReplaceTerminal<T, TProp>
ReplaceTerminal<T, TProp>
class
Terminal phase of a Replace rule — applies the predicate vocabulary.
RoundBuilder<T>
class
Two-step builder: first specify the precision via To(n), then close with the standard predicate vocabulary.
Methods
To(int decimals) : RoundTerminal<T>
Round todecimalsplaces usingToEven(banker's rounding).To(int decimals, MidpointRounding mode) : RoundTerminal<T>
Round todecimalsplaces with an explicit midpoint rule.ToInteger() : RoundTerminal<T>
RoundTerminal<T>
class
Terminal phase of a Round rule.
RuleBuilderBase<TBuilder, T>
abstract class
Common terminal vocabulary (When, Unless, Always, WhenAll, WhenAny) shared by all rule builders. Materializes the rule and registers it on the owning filter when a terminal is called.
Methods
Always() : ResponseFilter<T>Unless(AsyncPredicate<T> predicate) : ResponseFilter<T>Unless(Func<IResponseFilterContext, Task<bool>> predicate) : ResponseFilter<T>Unless(Func<IResponseFilterContext, bool> predicate) : ResponseFilter<T>Unless(Func<T, Task<bool>> predicate) : ResponseFilter<T>Unless(Func<T, bool> predicate) : ResponseFilter<T>Unless(Func<Task<bool>> predicate) : ResponseFilter<T>Unless(Func<bool> predicate) : ResponseFilter<T>Unless(SyncPredicate<T> predicate) : ResponseFilter<T>When(AsyncPredicate<T> predicate) : ResponseFilter<T>When(Func<IResponseFilterContext, Task<bool>> predicate) : ResponseFilter<T>When(Func<IResponseFilterContext, bool> predicate) : ResponseFilter<T>When(Func<T, Task<bool>> predicate) : ResponseFilter<T>When(Func<T, bool> predicate) : ResponseFilter<T>When(Func<Task<bool>> predicate) : ResponseFilter<T>When(Func<bool> predicate) : ResponseFilter<T>When(SyncPredicate<T> predicate) : ResponseFilter<T>WhenAll(AsyncPredicate<T>[] predicates) : ResponseFilter<T>WhenAny(AsyncPredicate<T>[] predicates) : ResponseFilter<T>WhenProperty(Func<PropertyInfo, bool> predicate) : TBuilder
SetToDefaultBuilder<T>
class
Builder for "reset properties to their default(TProperty)" rules.
SetValueBuilder<T, TProp>
class
Two-step builder: first specify the value via To(...), then close with When(...)/Unless(...)/Always().
Methods
To(Func<T, IResponseFilterContext, TProp> valueFactory) : SetValueTerminal<T, TProp>To(Func<T, TProp> valueFactory) : SetValueTerminal<T, TProp>To(TProp value) : SetValueTerminal<T, TProp>
SetValueTerminal<T, TProp>
class
Terminal phase of a SetValue rule — applies the predicate vocabulary.
TakeBuilder<T, TItem>
class
Two-step builder for limiting a collection property to the first N elements (or the last N).
Methods
First(int count) : TakeTerminal<T, TItem>
Keep only the firstcountitems.Last(int count) : TakeTerminal<T, TItem>
Keep only the lastcountitems.
TakeTerminal<T, TItem>
class
Terminal phase of a Take rule.
TransformBuilder<T, TProp>
class
Two-step builder: first specify the transform via Using(...), then close with When(...)/Unless(...)/Always().
Methods
Using(Func<T, TProp, IResponseFilterContext, TProp> transform) : TransformTerminal<T, TProp>Using(Func<T, TProp, TProp> transform) : TransformTerminal<T, TProp>Using(Func<TProp, TProp> transform) : TransformTerminal<T, TProp>
TransformKeyBuilder<T>
class
Two-step builder: first specify the key transform via Using(...), then close with the standard predicate vocabulary. The transform receives the property's serialized key (i.e. after any JsonNamingPolicy / [JsonPropertyName]) and returns the new key.
Methods
Using(Func<string, string> keyTransform) : TransformKeyTerminal<T>
TransformKeyTerminal<T>
class
Terminal phase of a TransformKey/TransformKeys rule — applies the predicate vocabulary.
TransformTerminal<T, TProp>
class
Terminal phase of a Transform rule — applies the predicate vocabulary.
TruncateBuilder<T>
class
Two-step builder: first specify the cutoff via After(...), then close with When(...)/Unless(...)/Always().
Methods
After(int maxLength) : TruncateTerminal<T>
Truncate aftermaxLengthcharacters. No suffix appended.After(int maxLength, string suffix) : TruncateTerminal<T>
Truncate aftermaxLengthand appendsuffixif a cut occurs.
TruncateTerminal<T>
class
Terminal phase of a Truncate rule.
Nextended.ResponseFilters.Extensions
ServiceCollectionExtensions
static class
DI registration for Nextended.ResponseFilters.
Extension methods
AddResponseFilter<TFilter>(this IServiceCollection services, ServiceLifetime lifetime = 1) : IServiceCollection
Register a single filter manually (useful for tests or runtime-built filters).AddResponseFilters(this IServiceCollection services, Assembly[] assemblies = null, ServiceLifetime lifetime = 1, Action<ResponseFilterOptions> configure = null) : IServiceCollection
Nextended.ResponseFilters.Json
JsonStructuralTransformer
static class
Serializes an object graph to a JsonNode and replays the StructuralEdits recorded in a StructuralEditBook against it — the only place a property can actually be removed, renamed, or have an extra key added, since a POCO can't express that at runtime.
Methods
Transform(object root, StructuralEditBook edits, JsonSerializerOptions options = null) : JsonNode
Serializerootand apply all edits fromedits. Returns the resultingJsonNode(which may benullwhenrootis null).
Nextended.ResponseFilters.Pipeline
IResponseFilterPipeline
interface
Entry point for filter execution. Walks an arbitrary object graph and applies all registered IResponseFilter instances whose target type matches a visited object.
Methods
ProcessAsync(object root, IResponseFilterContext context) : ValueTask
IResponseFilterRegistry
interface
Look-up by target type. Implementations should resolve filters from DI per request (so filters can have scoped dependencies) and may cache the type-to-implementation map.
Methods
GetFilters(Type type) : IReadOnlyList<IResponseFilter>
All filters registered fortype. Multiple filters per type are allowed and applied in registration order.HasFilters(Type type) : bool
True if any filter is registered fortype.
ResponseFilterPipeline
class
Default pipeline. Walks the response graph depth-first, dispatches matching filters per visited node, and (by default) lets exceptions propagate so domain errors reach the host's exception handler unchanged. Cycle-safe via ReferenceEqualityComparer.
Methods
ProcessAsync(object root, IResponseFilterContext context) : ValueTask
ResponseFilterRegistry
class
Default registry: scoped, looks up IResponseFilter implementations via DI and caches the type → filter-implementations mapping for the lifetime of the host.
Constructors
ResponseFilterRegistry(IServiceProvider services, ResponseFilterTypeMap typeMap)
Methods
GetFilters(Type type) : IReadOnlyList<IResponseFilter>HasFilters(Type type) : bool
ResponseFilterTypeMap
class
Process-wide cache of target type → filter implementation types. Populated at startup by AddResponseFilters; thread-safe for read.
Constructors
ResponseFilterTypeMap()
Methods
Add(Type targetType, Type filterImplType) : voidTryGet(Type targetType, out Type[] implTypes) : bool
Properties
TargetTypes : IEnumerable<Type> { get; }
All registered target types (snapshot — safe to enumerate).
TypeReachabilityCache
class
Precomputes "is any registered filter target reachable from rootType?" so the pipeline can early-out for responses that have nothing to filter. Walks the type graph once per root, caches the answer.
Constructors
TypeReachabilityCache()
Methods
MayBeAffected(Type rootType) : bool
True ifrootTypeitself or any reachable navigable property type matches a registered filter target. Conservative: returns true on uncertainty (e.g.Objectin the graph) to avoid false negatives.SetTargetTypes(IEnumerable<Type> targetTypes) : void
Nextended.ResponseFilters.Reflection
PropertyAccessor
class
Compiled delegate-based getter/setter for a PropertyInfo. Replaces PropertyInfo.GetValue / SetValue for hot-path use; ~10-50x faster than raw reflection. Instances are cached per PropertyInfo.
Methods
For(PropertyInfo property) : PropertyAccessorGetValue(object instance) : objectSetValue(object instance, object value) : void
Properties
CanRead : bool { get; }CanWrite : bool { get; }DeclaringType : Type { get; }Getter : Func<object, object> { get; }Property : PropertyInfo { get; }PropertyType : Type { get; }Setter : Action<object, object> { get; }