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.
SiteProjection (its sole consumer) uses 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. Every fetch carries HeaderName so the served request can fail fast (instead of deadlocking) if its render path awaits the projection — a future consumer of this fetcher outside the projection inherits that header and its tripwire semantics.
Constructors
RenderedHtmlFetcher
#public RenderedHtmlFetcher(IInProcessHttpDispatcher dispatcher, ILogger<RenderedHtmlFetcher> logger)
Initializes the fetcher with the in-process dispatcher and a logger.
Parameters
dispatcherIInProcessHttpDispatcherloggerILogger<RenderedHtmlFetcher>
Methods
FetchContentAsync
#public 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
pathstringselectorstringctCancellationToken
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. SiteProjection (its sole consumer) uses 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. Every fetch carries HeaderName so the served request can fail fast (instead of deadlocking) if its render path awaits the projection — a future consumer of this fetcher outside the projection inherits that header and its tripwire semantics.
public class RenderedHtmlFetcher
{
/// 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 Task<IElement> FetchContentAsync(string path, string selector, CancellationToken ct = default)
;
/// Initializes the fetcher with the in-process dispatcher and a logger.
public RenderedHtmlFetcher(IInProcessHttpDispatcher dispatcher, ILogger<RenderedHtmlFetcher> logger)
;
}