RenderedHtmlFetcher Pennington.Infrastructure
Fetches fully rendered page HTML from the running app and exposes a section of it (via CSS selector) as an AngleSharp IElement.
Both LlmsTxtService and SearchIndexService use this to get post-pipeline HTML — i.e., after Markdig extensions, Razor SSR, xref resolution, locale rewriting, and any other middleware have run. The pre-pipeline IContentRenderer path misses Razor pages entirely and misses request-pipeline transforms for everything else.
Requests are dispatched via IInProcessHttpDispatcher, which delivers them in-memory through TestServer (build mode + integration tests) or over Kestrel's listening socket (dev mode). The middleware pipeline runs identically in either case.
Constructors
.ctor
#public RenderedHtmlFetcher(IInProcessHttpDispatcher dispatcher, ILogger<RenderedHtmlFetcher> logger);Initializes the fetcher with the in-process dispatcher and a logger.
Parameters
dispatcherIInProcessHttpDispatcherloggerILogger<RenderedHtmlFetcher>
Methods
FetchContentAsync
#public async Task<IElement?> FetchContentAsync(string path, string? selector, CancellationToken ct = default);Fetches path from the running app, parses the response body as HTML, and returns the element matching selector. When selector is null or no match is found, returns Body. Returns null on non-success responses.
Parameters
pathstringselectorstring?ctCancellationToken (optional)
Returns
Task<IElement?>Pennington.Infrastructure.RenderedHtmlFetcher
namespace Pennington.Infrastructure;
/// Fetches fully rendered page HTML from the running app and exposes a section of it (via CSS selector) as an AngleSharp IElement. Both LlmsTxtService and SearchIndexService use this to get post-pipeline HTML — i.e., after Markdig extensions, Razor SSR, xref resolution, locale rewriting, and any other middleware have run. The pre-pipeline IContentRenderer path misses Razor pages entirely and misses request-pipeline transforms for everything else.Requests are dispatched via IInProcessHttpDispatcher, which delivers them in-memory through TestServer (build mode + integration tests) or over Kestrel's listening socket (dev mode). The middleware pipeline runs identically in either case.
public class RenderedHtmlFetcher
{
/// Initializes the fetcher with the in-process dispatcher and a logger.
public RenderedHtmlFetcher(IInProcessHttpDispatcher dispatcher, ILogger<RenderedHtmlFetcher> logger);
/// Fetches path from the running app, parses the response body as HTML, and returns the element matching selector. When selector is null or no match is found, returns Body. Returns null on non-success responses.
public async Task<IElement?> FetchContentAsync(string path, string? selector, CancellationToken ct = default);
}