Class HttpResponseOptionsBuilder<TDomain>
Fluent options builder for ToHttpResponse<T>(Result<T>, Action<HttpResponseOptionsBuilder<T>>?).
Selectors run against the TDomain value (not the projected response body).
public sealed class HttpResponseOptionsBuilder<TDomain>
Type Parameters
TDomainThe domain value type from
Result<TDomain>orWriteOutcome<TDomain>.
- Inheritance
-
HttpResponseOptionsBuilder<TDomain>
- Inherited Members
- Extension Methods
Remarks
Location options also supply a fallback for WriteOutcome.Created when the
outcome Location is null, empty, or whitespace. A nonblank outcome Location wins.
The outcome determines status; other outcome variants do not use builder locations.
Methods
Created(Func<TDomain, string>)
Returns 201 Created with a Location header derived from the domain value.
public HttpResponseOptionsBuilder<TDomain> Created(Func<TDomain, string> selector)
Parameters
Returns
- HttpResponseOptionsBuilder<TDomain>
Created(string)
Returns 201 Created with a literal Location header (e.g. /orders/123).
public HttpResponseOptionsBuilder<TDomain> Created(string locationLiteral)
Parameters
locationLiteralstring
Returns
- HttpResponseOptionsBuilder<TDomain>
CreatedAtAction(string, Func<TDomain, RouteValueDictionary>, string?)
Returns 201 Created with a relative Location path generated via LinkGenerator.GetPathByAction
(resolved from HttpContext.RequestServices at execute time). Equivalent to MVC's CreatedAtAction.
[RequiresUnreferencedCode("CreatedAtAction relies on MVC's ControllerLinkGeneratorExtensions which is not trim-safe. Use CreatedAtRoute with a named route for AOT/trim scenarios.")]
[RequiresDynamicCode("CreatedAtAction relies on MVC's ControllerLinkGeneratorExtensions which is not AOT-safe. Use CreatedAtRoute with a named route for AOT scenarios.")]
public HttpResponseOptionsBuilder<TDomain> CreatedAtAction(string actionName, Func<TDomain, RouteValueDictionary> routeValues, string? controllerName = null)
Parameters
actionNamestringThe action method name.
routeValuesFunc<TDomain, RouteValueDictionary>A function that returns a RouteValueDictionary for the new resource. Pass a RouteValueDictionary rather than an anonymous type to remain AOT-compatible.
controllerNamestringOptional controller name (defaults to the current controller).
Returns
- HttpResponseOptionsBuilder<TDomain>
Remarks
This method is not trim-safe / AOT-safe because MVC's ControllerLinkGeneratorExtensions
is not annotated. Use CreatedAtRoute(string, Func<TDomain, RouteValueDictionary>) with a named route instead for AOT scenarios.
CreatedAtRoute(string, Func<TDomain, RouteValueDictionary>)
Returns 201 Created with a relative Location path generated via LinkGenerator.GetPathByName
(resolved from HttpContext.RequestServices at execute time).
public HttpResponseOptionsBuilder<TDomain> CreatedAtRoute(string routeName, Func<TDomain, RouteValueDictionary> routeValues)
Parameters
routeNamestringThe route name.
routeValuesFunc<TDomain, RouteValueDictionary>A function that returns a RouteValueDictionary for the new resource. Pass a RouteValueDictionary rather than an anonymous type to remain AOT-compatible.
Returns
- HttpResponseOptionsBuilder<TDomain>
CreatedAtRoute(string, Func<TDomain, object>, string)
Convenience overload for the common single-id route shape (e.g. { ["id"] = order.Id.Value }).
Constructs the RouteValueDictionary from the supplied
id selector and route key, then chains CreatedAtRoute(string, Func<TDomain, RouteValueDictionary>).
public HttpResponseOptionsBuilder<TDomain> CreatedAtRoute(string routeName, Func<TDomain, object> idSelector, string idRouteKey = "id")
Parameters
routeNamestringThe route name.
idSelectorFunc<TDomain, object>A function that returns the id value for the new resource.
idRouteKeystringThe route-value key for the id (defaults to
"id").
Returns
- HttpResponseOptionsBuilder<TDomain>
EvaluatePreconditions()
Honors RFC 9110 conditional request headers (If-Match, If-Unmodified-Since,
If-None-Match, If-Modified-Since) on the response side. Only meaningful for
safe methods (GET/HEAD); on unsafe methods the precondition must be evaluated before the mutation.
public HttpResponseOptionsBuilder<TDomain> EvaluatePreconditions()
Returns
- HttpResponseOptionsBuilder<TDomain>
HonorPrefer()
Honors RFC 7240 Prefer: return=minimal/representation. Always emits Vary: Prefer
(appended; existing values preserved) and emits Preference-Applied only when honored.
public HttpResponseOptionsBuilder<TDomain> HonorPrefer()
Returns
- HttpResponseOptionsBuilder<TDomain>
Vary(params string[])
Appends the named headers to the response Vary header (existing values preserved).
public HttpResponseOptionsBuilder<TDomain> Vary(params string[] headers)
Parameters
headersstring[]
Returns
- HttpResponseOptionsBuilder<TDomain>
VaryForActor()
Appends the request header(s) that contribute to actor identity for the registered
IActorProvider to the response Vary header. The provider must
implement IProvideActorVaryHeaders; without that implementation the call
throws at apply time (fail-closed) rather than emit an incorrect or incomplete
Vary header that would allow intermediate caches to serve actor A's response
to actor B.
public HttpResponseOptionsBuilder<TDomain> VaryForActor()
Returns
- HttpResponseOptionsBuilder<TDomain>
Remarks
For the framework-bundled providers: ClaimsActorProvider /
EntraActorProvider emit Authorization (JWT-bearer assumption — override
VaryByHeaders in a subclass if your service uses cookies, mTLS, or another
non-bearer scheme); DevelopmentActorProvider emits the test header
(X-Test-Actor); CachingActorProvider delegates to the wrapped provider.
WithCacheControl(Func<TDomain, CacheControlHeaderValue?>)
Sets the Cache-Control response header from a selector run against the domain value.
Applies to success responses only — the failure path has no domain value.
public HttpResponseOptionsBuilder<TDomain> WithCacheControl(Func<TDomain, CacheControlHeaderValue?> selector)
Parameters
selectorFunc<TDomain, CacheControlHeaderValue>Selector invoked with the success-path domain value. Returning null from the selector skips the per-domain header on that response; when the static-value overload is also configured, that static value remains in place (the selector "refines, then falls back to static" rather than "overrides to nothing").
Returns
- HttpResponseOptionsBuilder<TDomain>
WithCacheControl(CacheControlHeaderValue)
Sets the Cache-Control response header from the supplied directive. Applied to
success responses (including 304 Not Modified) AND to failure responses, so a sensitive
endpoint declaring WithCacheControl(CacheControl.NoStore()) protects 404 / 403 /
validation responses from intermediate-cache leakage, not just the success-path
representation. Use the selector overload when the directive depends on the domain value
(e.g. a TTL derived from the resource).
public HttpResponseOptionsBuilder<TDomain> WithCacheControl(CacheControlHeaderValue value)
Parameters
valueCacheControlHeaderValueThe CacheControlHeaderValue whose ToString() is written to
Cache-Control.
Returns
- HttpResponseOptionsBuilder<TDomain>
Remarks
Use the framework-provided CacheControl presets for common shapes:
CacheControl.NoStore(), CacheControl.NoCache(),
CacheControl.Public(TimeSpan), CacheControl.Private(TimeSpan),
CacheControl.Immutable(TimeSpan). Each call returns a fresh instance so a consumer
mutating one value does not corrupt a later call.
WithContentLanguage(params string[])
Adds languages to the response Content-Language header.
public HttpResponseOptionsBuilder<TDomain> WithContentLanguage(params string[] languages)
Parameters
languagesstring[]
Returns
- HttpResponseOptionsBuilder<TDomain>
WithContentLocation(Func<TDomain, string>)
Sets the Content-Location header from the domain value.
public HttpResponseOptionsBuilder<TDomain> WithContentLocation(Func<TDomain, string> selector)
Parameters
Returns
- HttpResponseOptionsBuilder<TDomain>
WithETag(Func<TDomain, string>)
Sets a strong ETag derived from the domain value.
public HttpResponseOptionsBuilder<TDomain> WithETag(Func<TDomain, string> selector)
Parameters
Returns
- HttpResponseOptionsBuilder<TDomain>
WithETag(Func<TDomain, EntityTagValue>)
Sets an ETag (strong or weak) derived from the domain value.
public HttpResponseOptionsBuilder<TDomain> WithETag(Func<TDomain, EntityTagValue> selector)
Parameters
selectorFunc<TDomain, EntityTagValue>
Returns
- HttpResponseOptionsBuilder<TDomain>
WithErrorMapping(Func<Error, int>)
Per-call override mapper for failure responses. Highest precedence.
public HttpResponseOptionsBuilder<TDomain> WithErrorMapping(Func<Error, int> mapper)
Parameters
Returns
- HttpResponseOptionsBuilder<TDomain>
WithErrorMapping<TError>(int)
Per-call override for a single error type. Higher precedence than the global TrellisAspOptions.
public HttpResponseOptionsBuilder<TDomain> WithErrorMapping<TError>(int statusCode) where TError : Error
Parameters
statusCodeint
Returns
- HttpResponseOptionsBuilder<TDomain>
Type Parameters
TError
Exceptions
- ArgumentOutOfRangeException
Thrown when
statusCodeis outside 100–599.
WithLastModified(Func<TDomain, DateTimeOffset>)
Sets the Last-Modified header from the domain value.
public HttpResponseOptionsBuilder<TDomain> WithLastModified(Func<TDomain, DateTimeOffset> selector)
Parameters
selectorFunc<TDomain, DateTimeOffset>
Returns
- HttpResponseOptionsBuilder<TDomain>
WithLink(string, string)
Adds an RFC 8288 Link relation to the response.
public HttpResponseOptionsBuilder<TDomain> WithLink(string rel, string href)
Parameters
relstringA registered relation token (for example
describedby) or an absolute URI.hrefstringThe link target.
Returns
- HttpResponseOptionsBuilder<TDomain>
Remarks
Use describedby to point at a schema describing this resource, or
service-desc (RFC 8631) to point at an API description document such as an
OpenAPI file. Both are IANA-registered. schema is not a registered
relation type, and RFC 8288 §3.3 admits only a registered token or an absolute URI —
so a bare rel="schema" is non-conformant and generic clients ignore it. Register
your own extension relation as an absolute URI if neither registered relation fits.
Call this more than once to advertise several relations. Configured relations are
additive to the next/prev links emitted for a paginated response.
Exceptions
- ArgumentNullException
Thrown when
relorhrefis null.- ArgumentException
Thrown when
relis neither a valid relation token nor an absolute URI, or whenhrefis blank.
WithLocation(string, Func<TDomain, RouteValueDictionary>)
Adds a Location header to the response (status code unchanged — typically 200 OK),
generated as a relative path via LinkGenerator.GetPathByName at execute time. RFC 9110 §10.2.2 permits
Location on any 2xx response that identifies a related resource; use this on
state-transition endpoints that mutate an existing resource and want to point clients at
the canonical URL (e.g. POST /orders/{id}/return returning 200 OK).
public HttpResponseOptionsBuilder<TDomain> WithLocation(string routeName, Func<TDomain, RouteValueDictionary> routeValues)
Parameters
routeNamestringThe route name.
routeValuesFunc<TDomain, RouteValueDictionary>A function that returns a RouteValueDictionary for the resource being located.
Returns
- HttpResponseOptionsBuilder<TDomain>
Remarks
Unlike CreatedAtRoute(string, Func<TDomain, RouteValueDictionary>),
this does not set the status code to 201 Created — the response ships with its
natural 2xx status code. On Result<WriteOutcome<T>>, it supplies a
fallback for Created when the outcome's Location is null, empty, or whitespace;
the outcome still determines the status (201). A nonblank outcome Location wins.
Other outcome variants do not use builder locations, and Accepted monitor URIs are
unchanged. To version a builder-generated Location on either response path, chain
WithVersionedRoute() from Trellis.Asp.ApiVersioning.
WithLocation(string, Func<TDomain, object>, string)
Convenience overload for the common single-id route shape. Constructs the RouteValueDictionary from the supplied id selector and route key, then chains WithLocation(string, Func<TDomain, RouteValueDictionary>).
public HttpResponseOptionsBuilder<TDomain> WithLocation(string routeName, Func<TDomain, object> idSelector, string idRouteKey = "id")
Parameters
routeNamestringThe route name.
idSelectorFunc<TDomain, object>A function that returns the id value for the resource being located.
idRouteKeystringThe route-value key for the id (defaults to
"id").
Returns
- HttpResponseOptionsBuilder<TDomain>
WithLocationRouteResolver(Action<LocationRouteContext>)
Configures route values using the final Location destination at execution time. Runs after the route-values selector and all single-key route-value resolvers.
public HttpResponseOptionsBuilder<TDomain> WithLocationRouteResolver(Action<LocationRouteContext> resolver)
Parameters
resolverAction<LocationRouteContext>A callback that can inspect the destination and modify its per-execution route-values copy.
Returns
- HttpResponseOptionsBuilder<TDomain>
This builder for chaining.
Remarks
Replaces any previously configured Location-route resolver. Configuration order relative to CreatedAtRoute, CreatedAtAction, and WithLocation does not affect destination selection: the final destination wins. Ignored for literal/selector locations and outcome-owned URIs. Callback exceptions propagate.
WithRouteValueResolver(string, Func<HttpContext, string?>)
Registers a per-request resolver that injects (or overrides) a single route-value entry
at Location-header generation time. Invoked AFTER the
CreatedAtRoute(string, Func<TDomain, RouteValueDictionary>) / CreatedAtAction(string, Func<TDomain, RouteValueDictionary>, string?) route-values selector runs;
if the resolver returns non-null, the value is set under key in the
resulting RouteValueDictionary (overriding any
existing entry under the same key). If the resolver returns null, the entry is left
untouched.
public HttpResponseOptionsBuilder<TDomain> WithRouteValueResolver(string key, Func<HttpContext, string?> resolver)
Parameters
keystringThe route-value key to inject.
resolverFunc<HttpContext, string>The per-request resolver. Receives the active HttpContext; returns the value to inject, or null to skip.
Returns
- HttpResponseOptionsBuilder<TDomain>
Remarks
Designed for cross-cutting per-request concerns such as API versioning (a Location header that round-trips the requested version), tenant id, or culture. Multiple resolvers can be registered with distinct keys; calling this method again with the same key replaces the previous resolver. Useful with CreatedAtRoute(string, Func<TDomain, RouteValueDictionary>), CreatedAtAction(string, Func<TDomain, RouteValueDictionary>, string?) and WithLocation(string, Func<TDomain, RouteValueDictionary>); ignored by literal/selector Location modes.