Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A response can be correct for the current request and still corrupt what a later reader receives. If a response filter translates a DTO that is also stored in a shared cache, assigning translated text changes the cached object itself. Keep cached or domain data authoritative; apply request-specific presentation rules to response-owned output.

How a correct response can leave the wrong state behind

Consider an ASP.NET Core endpoint that returns catalogue text from an in-process cache. A response filter localizes that text by assigning translated strings to the returned DTO. If the DTO is the same object held by the cache, the filter has changed shared state—not just the outgoing response.

The translated response may look right, so checking only that first response misses the ownership bug. A later request for the source language, or a background consumer reading the cached object, can now receive the translated presentation text as if it were authoritative source data.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep data, presentation context, and output separate

  • Cached or domain data: the authoritative input, which should not change just because one request needs a different presentation.
  • Request context: the selector for presentation rules, such as the requested language.
  • HTTP response: request-specific output that can be transformed without writing back to cache-owned or caller-owned objects.

The guiding rule is: “The practical rule is short: if a value is shared, treat it as immutable.” — Ivan Rossouw, author of “Project the Response, Not the Cache”, listed as posted October 1, 2026.

Choose an output strategy that preserves ownership

No single API is right for every application. Choose based on the serializer contract and the constraints of the response pipeline; the invariant is that request-specific work must not mutate a shared input.

Map to a dedicated response model

Create a response model from the cached or domain object, then apply presentation changes to the new model. This makes the boundary explicit and is often useful when the public payload differs from the internal representation. The trade-off is mapping code and the cost of constructing another representation.

Clone before changing values

Copy the object graph, then transform the copy. The copy must include mutable nested objects and collections: a shallow copy can still leave the filter modifying objects shared with the cache. Cloning can be practical when the response shape should otherwise remain unchanged, but the copying rules must be clear and maintained.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Project while materializing the response

Where the serializer contract allows it, substitute presentation values as the response is materialized rather than assigning them to the cached DTO. This can avoid maintaining a separate mapping layer, but it makes serializer behavior and response-pipeline coverage especially important.

Preserve a cheap path and define failure behavior

When a request already uses the source representation, keep a pass-through path rather than projecting every response unnecessarily. A transformed response can require JSON materialization, lookup work, and temporary allocations. Measure that path using representative payload sizes; no universal performance percentage follows from the design alone.

Decide what happens if projection fails before enabling it. For a presentation-only feature, returning an untransformed response may be an acceptable feature failure. For sensitive values that must be redacted, falling back to the original payload could be a security failure; that case should fail closed. Also decide whether errors and security-sensitive or otherwise exempt payloads should bypass transformation.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Test the next reader, not just the first response

A snapshot of the transformed response proves only that the current output looks right. A sequence test checks the ownership invariant across readers:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Place an object containing source-language text in the cache implementation used by the host.
  2. Request the transformed representation and verify the response contains the expected presentation text.
  3. Read the cached object again and verify its source value has not changed.
  4. Request the source representation and verify that it still contains the original text.

Where practical, run this test through the real result filter, cache, and serializer configuration. Add focused cases for nested collections, wrappers, explicit JSON results, error and exempt payloads, and projection failure. These paths can behave differently from a simple DTO response, so test them where the application supports them.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.