Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Anatomy of ASP.NET Core Requests (60m)

Steve Gordon
June 04, 2020
3.2k

Anatomy of ASP.NET Core Requests (60m)

Have you ever wondered how a browser/client request actually results in a response from ASP.NET Core? Have you ever been constrained by the default behaviour of ASP.NET Core and wanted to change how it works? If so, then this talk is for you.

In this session, Steve will explore the lifecycle of incoming requests in ASP.NET Core, touring through the layers from Kestrel, to hosting, to middleware and then on into MVC itself. You'll see how the pieces all fit together and learn about the places where you can inject your own implementations to customise, augment and override the ASP.NET Core defaults.

Steve will show the hidden extension points that can take you to power-user levels when building your ASP.NET Core applications, such as applying custom conventions, filters and model binding behaviour. You'll leave this talk with ideas for improving your ASP.NET Core applications and reducing code by refactoring cross-cutting concerns.

Don't fight the framework, customise it!

In this session, I provide an in-depth look at how ASP.NET Core processes HTTP requests. I'll describe the flow through the application host, the Kestrel web server, middleware and finally through MVC. The intent is to use this narrative to explain some advanced features of ASP.NET Core which support customising its behaviour.

Key take-aways:
- How application hosting works
- How Kestrel receives requests from the network Socket and parses them
- How the middleware pipeline can be used to respond to requests
- How endpoint routing works
- How filters can be used to intercept and modify requests within MVC
- How MVC finally handles a request.

This session is aimed at ASP.NET Core developers of intermediate/advanced experience.

Steve Gordon

June 04, 2020
Tweet

More Decks by Steve Gordon

Transcript

  1. Anatomy of ASP.NET Core
    Requests
    Steve Gordon
    @stevejgordon | stevejgordon.co.uk
    Resources: http://bit.ly/aspnetanatomy

    View full-size slide

  2. CLIENT HTTP REQUEST
    www.stevejgordon.co.uk/api/books

    View full-size slide

  3. Recursive
    Resolver
    Client
    Root-Level DNS
    Top Level Domain
    DNS (.uk)
    Second-Level
    DNS (.co.uk)
    queries
    refers
    refers
    IP Address
    Domain Name
    Server
    (stevejgordon.co.uk)
    refers

    View full-size slide

  4. Client
    (::64000)
    Web Server
    (101.101.121.64:443)
    ClientHello
    ServerHello
    Certificate
    ServerHelloDone
    ClientKeyExchange
    ChangeCipherSpec
    Finished
    ChangeCipherSpec
    Finished
    TCP
    TLS

    View full-size slide

  5. @stevejgordon
    www.stevejgordon.co.uk
    GET /api/books HTTP/1.1
    Host: stevejgordon.co.uk
    Accept: application/json, text/plain, */*
    Accept-Language: en-GB
    Accept-Encoding: br, gzip, deflate
    User-Agent: ClientApplication/1.0
    (blank line)

    View full-size slide

  6. @stevejgordon
    www.stevejgordon.co.uk
    GET /api/books HTTP/1.1
    Host: stevejgordon.co.uk
    Accept: application/json, text/plain, */*
    Accept-Language: en-GB
    Accept-Encoding: br, gzip, deflate
    User-Agent: ClientApplication/1.0
    (blank line)

    View full-size slide

  7. @stevejgordon
    www.stevejgordon.co.uk
    GET /api/books HTTP/1.1
    Host: stevejgordon.co.uk
    Accept: application/json, text/plain, */*
    Accept-Language: en-GB
    Accept-Encoding: br, gzip, deflate
    User-Agent: ClientApplication/1.0
    (blank line)

    View full-size slide

  8. @stevejgordon
    www.stevejgordon.co.uk
    GET /api/books HTTP/1.1
    Host: stevejgordon.co.uk
    Accept: application/json, text/plain, */*
    Accept-Language: en-GB
    Accept-Encoding: br, gzip, deflate
    User-Agent: ClientApplication/1.0
    (blank line)

    View full-size slide

  9. Client Internet
    KESTREL
    HTTP/S
    R e q u e s t
    R e s p o n s e
    Accept Connection
    ASP.NET Core
    Connection Middleware
    Listening on :80 and :443

    View full-size slide

  10. Kestrel
    Client Internet
    ASP.NET CORE
    {}
    Application
    Code
    HTTP/S
    HttpContext
    R e q u e s t
    R e s p o n s e
    Parse HTTP
    request

    View full-size slide

  11. Kestrel
    Client Internet
    ASP.NET CORE
    HTTP/S
    HttpContext
    Middleware
    Endpoint / MVC
    R e q u e s t
    R e s p o n s e

    View full-size slide

  12. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    });
    }

    View full-size slide

  13. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    });
    }

    View full-size slide

  14. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    });
    }

    View full-size slide

  15. @stevejgordon
    www.stevejgordon.co.uk
    R e q u e s t
    R e s p o n s e
    Endpoint Handles Request
    Pipeline Invoked
    HttpsRedirectionMiddleware
    EndpointRoutingMiddleware
    AuthenticationMiddleware
    AuthorizationMiddleware
    EndpointMiddleware
    DeveloperExceptionPageMiddleware
    ForwardedHeadersMiddleware
    HostFilteringMiddleware

    View full-size slide

  16. @stevejgordon
    www.stevejgordon.co.uk
    R e q u e s t
    R e s p o n s e
    Endpoint Handles Request
    Pipeline Invoked
    HttpsRedirectionMiddleware
    EndpointRoutingMiddleware
    AuthenticationMiddleware
    AuthorizationMiddleware
    EndpointMiddleware
    DeveloperExceptionPageMiddleware
    ForwardedHeadersMiddleware
    HostFilteringMiddleware

    View full-size slide

  17. @stevejgordon
    www.stevejgordon.co.uk
    R e q u e s t
    R e s p o n s e
    Endpoint Handles Request
    Pipeline Invoked
    HttpsRedirectionMiddleware
    EndpointRoutingMiddleware
    AuthenticationMiddleware
    AuthorizationMiddleware
    EndpointMiddleware
    DeveloperExceptionPageMiddleware
    ForwardedHeadersMiddleware
    HostFilteringMiddleware

    View full-size slide

  18. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    app.Use(async (ctx, next) =>
    {
    var sw = Stopwatch.StartNew();
    await next(); // call next middleware in pipeline
    sw.Stop();
    var recorder = ctx.RequestServices.GetRequiredService();
    recorder.RecordRequest(ctx.Response.StatusCode, sw.ElapsedMilliseconds);
    });
    ...
    }

    View full-size slide

  19. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    app.Use(async (ctx, next) =>
    {
    var sw = Stopwatch.StartNew();
    await next(); // call next middleware in pipeline
    sw.Stop();
    var recorder = ctx.RequestServices.GetRequiredService();
    recorder.RecordRequest(ctx.Response.StatusCode, sw.ElapsedMilliseconds);
    });
    ...
    }

    View full-size slide

  20. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    app.Use(async (ctx, next) =>
    {
    var sw = Stopwatch.StartNew();
    await next(); // call next middleware in pipeline
    sw.Stop();
    var recorder = ctx.RequestServices.GetRequiredService();
    recorder.RecordRequest(ctx.Response.StatusCode, sw.ElapsedMilliseconds);
    });
    ...
    }

    View full-size slide

  21. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    app.Use(async (ctx, next) =>
    {
    var sw = Stopwatch.StartNew();
    await next(); // call next middleware in pipeline
    sw.Stop();
    var recorder = ctx.RequestServices.GetRequiredService();
    recorder.RecordRequest(ctx.Response.StatusCode, sw.ElapsedMilliseconds);
    });
    ...
    }

    View full-size slide

  22. @stevejgordon
    www.stevejgordon.co.uk
    public class MetricMiddleware
    {
    private readonly RequestDelegate _next;
    private readonly IMetricRecorder _metricRecorder;
    public MetricMiddleware(RequestDelegate next, IMetricRecorder metricRecorder)
    {
    _next = next;
    _metricRecorder = metricRecorder;
    }
    public async Task InvokeAsync(HttpContext ctx)
    {
    var stopWatch = Stopwatch.StartNew();
    await _next(ctx);
    stopWatch.Stop();
    _metricRecorder.RecordRequest(ctx.Response.StatusCode, stopWatch.ElapsedMilliseconds);
    }
    }

    View full-size slide

  23. @stevejgordon
    www.stevejgordon.co.uk
    public class MetricMiddleware
    {
    private readonly RequestDelegate _next;
    private readonly IMetricRecorder _metricRecorder;
    public MetricMiddleware(RequestDelegate next, IMetricRecorder metricRecorder)
    {
    _next = next;
    _metricRecorder = metricRecorder;
    }
    public async Task InvokeAsync(HttpContext ctx)
    {
    var stopWatch = Stopwatch.StartNew();
    await _next(ctx);
    stopWatch.Stop();
    _metricRecorder.RecordRequest(ctx.Response.StatusCode, stopWatch.ElapsedMilliseconds);
    }
    }

    View full-size slide

  24. @stevejgordon
    www.stevejgordon.co.uk
    public class MetricMiddleware
    {
    private readonly RequestDelegate _next;
    private readonly IMetricRecorder _metricRecorder;
    public MetricMiddleware(RequestDelegate next, IMetricRecorder metricRecorder)
    {
    _next = next;
    _metricRecorder = metricRecorder;
    }
    public async Task InvokeAsync(HttpContext ctx)
    {
    var stopWatch = Stopwatch.StartNew();
    await _next(ctx);
    stopWatch.Stop();
    _metricRecorder.RecordRequest(ctx.Response.StatusCode, stopWatch.ElapsedMilliseconds);
    }
    }

    View full-size slide

  25. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    app.UseMiddleware();
    ...
    }

    View full-size slide

  26. @stevejgordon
    www.stevejgordon.co.uk
    public static class MetricMiddlewareExtensions
    {
    public static IApplicationBuilder UseMetrics(this IApplicationBuilder builder)
    {
    return builder.UseMiddleware();
    }
    }

    View full-size slide

  27. @stevejgordon
    www.stevejgordon.co.uk
    public static class MetricMiddlewareExtensions
    {
    public static IApplicationBuilder UseMetrics(this IApplicationBuilder builder)
    {
    return builder.UseMiddleware();
    }
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    app.UseMetrics();
    ...
    }

    View full-size slide

  28. ENDPOINT ROUTING

    View full-size slide

  29. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    });
    }

    View full-size slide

  30. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    });
    }

    View full-size slide

  31. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    });
    }
    Routing Zone

    View full-size slide

  32. @stevejgordon
    www.stevejgordon.co.uk
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    });
    }
    Endpoint Aware

    View full-size slide

  33. ASP.NET CORE MVC

    View full-size slide

  34. @stevejgordon
    www.stevejgordon.co.uk
    [ApiController]
    [Route("[controller]")]
    public class BooksController : ControllerBase
    {
    private readonly IBookRepository _bookRepository;
    public BooksController(IBookRepository bookRepository)
    {
    _bookRepository = bookRepository;
    }
    [HttpGet]
    public ActionResult> Get()
    {
    return Ok(_bookRepository.GetAll());
    }
    ...
    }

    View full-size slide

  35. @stevejgordon
    www.stevejgordon.co.uk
    [ApiController]
    [Route("[controller]")]
    public class BooksController : ControllerBase
    {
    private readonly IBookRepository _bookRepository;
    public BooksController(IBookRepository bookRepository)
    {
    _bookRepository = bookRepository;
    }
    [HttpGet]
    public ActionResult> Get()
    {
    return Ok(_bookRepository.GetAll());
    }
    ...
    }

    View full-size slide

  36. @stevejgordon
    www.stevejgordon.co.uk
    [ApiController]
    [Route("[controller]")]
    public class BooksController : ControllerBase
    {
    private readonly IBookRepository _bookRepository;
    public BooksController(IBookRepository bookRepository)
    {
    _bookRepository = bookRepository;
    }
    [HttpGet]
    public ActionResult> Get()
    {
    return Ok(_bookRepository.GetAll());
    }
    ...
    }

    View full-size slide

  37. @stevejgordon
    www.stevejgordon.co.uk
    [ApiController]
    [Route("[controller]")]
    public class BooksController : ControllerBase
    {
    private readonly IBookRepository _bookRepository;
    public BooksController(IBookRepository bookRepository)
    {
    _bookRepository = bookRepository;
    }
    [HttpGet]
    public ActionResult> Get()
    {
    return Ok(_bookRepository.GetAll());
    }
    ...
    }

    View full-size slide

  38. @stevejgordon
    www.stevejgordon.co.uk
    Controller
    Initialisation
    Action
    Execution
    View
    Rendering
    Result
    Execution Response
    View Result
    Data Result
    Controller Factory
    Controller Action
    Invoker

    View full-size slide

  39. Authorization
    Filters
    R e q u e s t
    R e s p o n s e
    Middleware
    Forbidden
    void OnAuthorization(AuthorizationFilterContext ctx)

    View full-size slide

  40. Resource
    Filters
    Authorization
    Filters
    R e q u e s t
    R e s p o n s e
    Middleware
    Short-circuit
    void OnResourceExecuting(ResourceExecutingContext ctx);
    void OnResourceExecuted(ResourceExecutedContext ctx);

    View full-size slide

  41. Resource
    Filters
    Middleware
    Filters
    Authorization
    Filters
    R e q u e s t
    R e s p o n s e
    Middleware
    Short-circuit

    View full-size slide

  42. @stevejgordon
    www.stevejgordon.co.uk
    public class CompressionMiddlewarePipeline
    {
    public void Configure(IApplicationBuilder app)
    {
    app.UseResponseCompression();
    }
    }

    View full-size slide

  43. @stevejgordon
    www.stevejgordon.co.uk
    public class CompressionMiddlewarePipeline
    {
    public void Configure(IApplicationBuilder app)
    {
    app.UseResponseCompression();
    }
    }
    [ApiController]
    [Route("[controller]")]
    [MiddlewareFilter(typeof(CompressionMiddlewarePipeline))]
    public class AuthorsController : ControllerBase
    {
    // Action methods
    }

    View full-size slide

  44. @stevejgordon
    www.stevejgordon.co.uk
    public class CompressionMiddlewarePipeline
    {
    public void Configure(IApplicationBuilder app)
    {
    app.UseResponseCompression();
    }
    }
    [ApiController]
    [Route("[controller]")]
    [MiddlewareFilter(typeof(CompressionMiddlewarePipeline))]
    public class AuthorsController : ControllerBase
    {
    // Action methods
    }

    View full-size slide

  45. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Authorization
    Filters
    R e q u e s t
    R e s p o n s e
    Middleware

    View full-size slide

  46. CONTROLLER
    ACTION INVOKER

    View full-size slide

  47. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Model Binding
    Authorization
    Filters
    R e q u e s t
    R e s p o n s e
    Middleware

    View full-size slide

  48. MODEL BINDERS

    View full-size slide

  49. @stevejgordon
    www.stevejgordon.co.uk
    [HttpGet]
    public ActionResult> Search(string keyword, int pageSize)
    {
    return Ok(_bookRepository.Search(keyword, pageSize));
    }
    GET /books/search?keyword=performance&pageSize=10

    View full-size slide

  50. @stevejgordon
    www.stevejgordon.co.uk
    [HttpGet]
    public ActionResult> Search(string keyword, int pageSize)
    {
    return Ok(_bookRepository.Search(keyword, pageSize));
    }
    GET /books/search?keyword=performance&pageSize=10

    View full-size slide

  51. @stevejgordon
    www.stevejgordon.co.uk
    [HttpGet]
    public ActionResult> Search(string keyword, int pageSize)
    {
    return Ok(_bookRepository.Search(keyword, pageSize));
    }
    GET /books/search?keyword=performance&pageSize=10

    View full-size slide

  52. @stevejgordon
    www.stevejgordon.co.uk
    [HttpGet]
    public ActionResult> Search(string keyword, int pageSize)
    {
    return Ok(_bookRepository.Search(keyword, pageSize));
    }
    GET /books/search?keyword=performance&pageSize=10

    View full-size slide

  53. @stevejgordon
    www.stevejgordon.co.uk
    [HttpGet]
    public ActionResult> Search(string keyword, int pageSize)
    {
    return Ok(_bookRepository.Search(keyword, pageSize));
    }
    GET /books/search?keyword=performance&pageSize=10

    View full-size slide

  54. @stevejgordon
    www.stevejgordon.co.uk
    [HttpPost]
    public IActionResult CreateBook(BookInputModel book)
    {
    // Save the Book...
    return Ok();
    }
    public class BookInputModel
    {
    public int Id { get; set; }
    public string Title { get; set; }
    public string ISBN { get; set; }
    }

    View full-size slide

  55. INPUT FORMATTERS

    View full-size slide

  56. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Model Binding
    Authorization
    Filters
    Action Filters
    R e q u e s t
    R e s p o n s e
    Middleware
    Short-circuit
    void OnActionExecuting(ActionExecutingContext ctx);

    View full-size slide

  57. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Model Binding
    Authorization
    Filters
    Action Filters
    Action
    Execution
    R e q u e s t
    R e s p o n s e
    Middleware
    void OnActionExecuted(ActionExecutedContext ctx);

    View full-size slide

  58. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Model Binding
    Authorization
    Filters
    Action Filters
    Exception
    Filters
    Action
    Execution
    R e q u e s t
    R e s p o n s e
    Middleware
    void OnException(ExceptionContext context);

    View full-size slide

  59. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Model Binding
    Authorization
    Filters
    Action Filters Result Filters
    Exception
    Filters
    Action
    Execution
    R e q u e s t
    R e s p o n s e
    Middleware
    void OnResultExecuting(ResultExecutingContext ctx);

    View full-size slide

  60. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Model Binding
    Authorization
    Filters
    Action Filters Result Filters
    Exception
    Filters
    Action
    Execution
    ActionResult
    Executed
    Output
    Formatter
    R e q u e s t
    R e s p o n s e
    Middleware

    View full-size slide

  61. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Model Binding
    Authorization
    Filters
    Action Filters Result Filters
    Exception
    Filters
    Action
    Execution
    ActionResult
    Executed
    Resource
    Filters
    Middleware
    Filters
    Output
    Formatter
    R e q u e s t
    R e s p o n s e
    Middleware
    Result Filters
    void OnResultExecuted(ResultExecutedContext ctx);

    View full-size slide

  62. Resource
    Filters
    Middleware
    Filters
    Controller
    Created
    Model Binding
    Authorization
    Filters
    Action Filters Result Filters
    Exception
    Filters
    Action
    Execution
    ActionResult
    Executed
    Resource
    Filters
    Middleware
    Filters
    Output
    Formatter
    R e q u e s t
    R e s p o n s e
    Middleware
    Result Filters

    View full-size slide

  63. @stevejgordon
    www.stevejgordon.co.uk
    R e q u e s t
    R e s p o n s e
    Endpoint Handles Request
    Pipeline Invoked
    HttpsRedirectionMiddleware
    EndpointRoutingMiddleware
    AuthenticationMiddleware
    AuthorizationMiddleware
    EndpointMiddleware
    DeveloperExceptionPageMiddleware
    ForwardedHeadersMiddleware
    HostFilteringMiddleware

    View full-size slide

  64. Kestrel
    Client Internet
    ASP.NET CORE
    HTTP/S
    HttpContext
    Middleware
    MVC
    R e q u e s t
    R e s p o n s e

    View full-size slide

  65. @stevejgordon
    www.stevejgordon.co.uk
    HTTP/1.1 200 OK
    Date: Sat, 23 May 2020 07:20:56 GMT
    Content-Type: application/json; charset=utf-8
    Server: Kestrel
    Transfer-Encoding: chunked
    Last-Modified: Tue, 31 Mar 2020 23:00:00 GMT
    [{"id":1,"title":"Pro .NET Memory
    Management","isbn":"978-1-4842-4026-
    7","datePublished":"2018-11-
    13T00:00:00","authors":[{"firstName":"Konrad","lastNam
    e":"Kokosa"}],"lastModified":"2020-04-01T00:00:00"}]

    View full-size slide

  66. @stevejgordon
    www.stevejgordon.co.uk
    HTTP/1.1 200 OK
    Date: Sat, 23 May 2020 07:20:56 GMT
    Content-Type: application/json; charset=utf-8
    Server: Kestrel
    Transfer-Encoding: chunked
    Last-Modified: Tue, 31 Mar 2020 23:00:00 GMT
    [{"id":1,"title":"Pro .NET Memory
    Management","isbn":"978-1-4842-4026-
    7","datePublished":"2018-11-
    13T00:00:00","authors":[{"firstName":"Konrad","lastNam
    e":"Kokosa"}],"lastModified":"2020-04-01T00:00:00"}]

    View full-size slide

  67. @stevejgordon
    www.stevejgordon.co.uk
    HTTP/1.1 200 OK
    Date: Sat, 23 May 2020 07:20:56 GMT
    Content-Type: application/json; charset=utf-8
    Server: Kestrel
    Transfer-Encoding: chunked
    Last-Modified: Tue, 31 Mar 2020 23:00:00 GMT
    [{"id":1,"title":"Pro .NET Memory
    Management","isbn":"978-1-4842-4026-
    7","datePublished":"2018-11-
    13T00:00:00","authors":[{"firstName":"Konrad","lastNam
    e":"Kokosa"}],"lastModified":"2020-04-01T00:00:00"}]

    View full-size slide

  68. @stevejgordon
    www.stevejgordon.co.uk
    HTTP/1.1 200 OK
    Date: Sat, 23 May 2020 07:20:56 GMT
    Content-Type: application/json; charset=utf-8
    Server: Kestrel
    Transfer-Encoding: chunked
    Last-Modified: Tue, 31 Mar 2020 23:00:00 GMT
    [{"id":1,"title":"Pro .NET Memory
    Management","isbn":"978-1-4842-4026-
    7","datePublished":"2018-11-
    13T00:00:00","authors":[{"firstName":"Konrad","lastNam
    e":"Kokosa"}],"lastModified":"2020-04-01T00:00:00"}]

    View full-size slide

  69. @stevejgordon
    www.stevejgordon.co.uk
    Summary
    • HTTP request received and
    parsed by Kestrel
    • Middleware pipeline
    executed
    • An endpoint (MVC) handles
    the request
    • Filter pipeline
    • Action execution
    • ActionResult execution

    View full-size slide

  70. THANK YOU
    www.stevejgordon.co.uk
    https://app.pluralsight.com/profile/author/steve-gordon
    http://bit.ly/aspnetanatomy
    @stevejgordon

    View full-size slide