liveBook · Manning

Result filter

As explained in ASP.NET Core in Action, 3e

IResultFilter is an ASP.NET Core interface for synchronous MVC filters that run before and after result execution.

A result filter runs immediately before and after an MVC action result (`IActionResult`) executes. Use one when you need to adjust how a result produces a response, rather than change the action’s business logic. Result filters are part of the MVC and Razor Pages filter pipeline, not the general middleware pipeline. section 22.1.5 section 21.1 section 21.3

For a synchronous filter, implement `IResultFilter` or derive from `ResultFilterAttribute`. Put work that must happen before result execution in `OnResultExecuting`; the corresponding executed method runs afterward. Choose the asynchronous interface, `IAsyncResultFilter`, if the filter needs asynchronous calls. Do not implement both interfaces: only the asynchronous one will be used. section 21.4 section 22.1.5

Add a Last-Modified header

Suppose an API action returns an `OkObjectResult` containing a detail view model with a `LastModified` value. In `OnResultExecuting`, check both the result type and its value, then set `context.HttpContext.Response.GetTypedHeaders().LastModified` from that value. The checks keep the filter from assuming every action returns the same object. section 22.1.5

Listing 22.9 Setting a response header in a result filter
public class AddLastModifedHeaderAttribute : ResultFilterAttribute   #1
{
    public override void OnResultExecuting(                          #2
        ResultExecutingContext context)                              #2
    {
        if (context.Result is OkObjectResult result                  #3
            && result.Value is RecipeDetailViewModel detail)         #4
        {
            var viewModelDate = detail.LastModified;                 #5
            context.HttpContext.Response                             #5
              .GetTypedHeaders().LastModified = viewModelDate;       #5
        }
    }
}

The listing shows the result-type checks and header assignment inside `OnResultExecuting`. section 22.1.5

Built-in result filters offer other uses: `ProducesAttribute` specifies an API output format, while `FormatFilterAttribute` selects a format from a route value or `format` query parameter. XML output also requires XML formatters to be configured. section 22.1.5

Watch for short-circuits. If an authorization, resource, or exception filter supplies the result, an ordinary result filter does not run; use `IAlwaysRunResultFilter` when its transformation must also apply to those results. An action or page filter that skips its handler still allows result filters to run. Exception filters do not catch exceptions thrown by result filters. section 22.2 section 22.1.4

How ASP.NET Core in Action, 3e covers it

How deep it goes
Explains pipeline timing, synchronous implementation, and short-circuit behavior through a header example; does not develop a larger custom filter.
Examples
Shows a `Last-Modified` response header and built-in filters selecting XML or a format named in a URL.
What it assumes
Assumes familiarity with C# classes and MVC action results while introducing filter interfaces and their place in the pipeline.
What you can do after
Build it from scratch to adjust a result before execution, and choose an always-run filter when short-circuited results need the adjustment.
How it connects
Connects result filters to `IActionResult`, action filters, middleware, output formatters, and pipeline short-circuiting.

Also explained in

Compare how 2 books explain result filter →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.