MvcOptions Default { get; }
Source
Gets a new default instance of MvcOptions
configured with MvcSupport.Controllers
.
Provides a static entry point for starting a web application with a custom startup class and root module.
TStartup
WebStartup{TModule}
.TModule
Task RunAsync(string[] args, Action<WebOptions>? configureOptions = null)
Asynchronously runs the web application using the specified command-line arguments and optional option configuration.
args
configureOptions
WebOptions
during startup.
A Task
representing the asynchronous operation of running the web application.
Provides a simplified static entry point for starting a web application using a default startup configuration.
TModule
Task RunAsync(string[] args, Action<WebOptions>? configureOptions = null)
Asynchronously runs the web application with a default startup using the specified command-line arguments and optional configuration.
args
configureOptions
WebOptions
during startup.
A Task
representing the asynchronous operation of running the web application.
Represents configuration options for ASP.NET Core MVC services and features.
MvcOptions Default { get; }
Source
Gets a new default instance of MvcOptions
configured with MvcSupport.Controllers
.
MvcSupport MvcSupportLevel { get; init; }
Source
Gets the level of MVC support to register (e.g., Controllers only, or Controllers with Views).
Action<IMvcBuilder>? ConfigureMvc { get; init; }
Source
Gets an optional delegate for performing advanced configuration of the IMvcBuilder
.
string Build(PathString pathBase, PwaOptions options, IFileVersionProvider? fileVersionProvider = null)
Builds the exact encoded PWA head markup shared by the Razor TagHelper and development diagnostics.
pathBase
options
fileVersionProvider
Encoded head markup, or an empty string when no PWA surface is active.
Tracks legacy and current service-worker path assignments without making configuration-provider order observable.
void SetLegacyValue(string value)
Records an explicit assignment through the legacy offline compatibility property.
value
void SetWorkerValue(string value)
Records an explicit assignment through the current worker property.
value
bool LegacyWasSet { get; set; }
Source
Gets a value indicating whether the legacy offline path property was assigned explicitly.
bool WorkerWasSet { get; set; }
Source
Gets a value indicating whether the current worker path property was assigned explicitly.
bool HasConflict { get; }
Source
Gets a value indicating whether the legacy and current properties were assigned different paths.
string EffectiveValue { get; }
Source
Gets the current worker path, preferring the current property over the legacy compatibility property.
Configures immutable metadata and request-input requirements for a named canary registration.
Registration snapshots these values after the callback completes. Retaining and later mutating this options object or its tag set does not change the registered descriptor.
void RequireMarker()
Makes the marker header required. Repeated calls are idempotent.
void RequireFreshSince()
Makes the freshness header required. Repeated calls are idempotent.
string? DisplayName { get; set; }
Source
Gets or sets the nonblank display name. It defaults to the registered name.
string? Description { get; set; }
Source
Gets or sets an optional description of at most 512 characters.
ISet<string> Tags { get; }
Source
Gets the mutable registration-time set of lowercase canary metadata tags.
ISet<string> AllowedDetailKeys { get; }
Source
Gets the mutable registration-time set of detail keys an evaluator may return.
Registration snapshots this set. At most sixteen keys may be declared. Keys use the same 1-64 character, lowercase, dot-separated grammar as AppSurfaceCanaryResultOptions.AddDetail
. Declaration bounds response shape; it does not classify, sanitize, or redact the values supplied by an application evaluator.
bool MarkerRequired { get; set; }
Source
Gets a value indicating whether the marker header is required.
bool FreshSinceRequired { get; set; }
Source
Gets a value indicating whether the freshness header is required.
Represents configuration options for serving static files and web assets.
StaticFilesOptions Default { get; }
Source
Gets a default instance of StaticFilesOptions
with default configuration settings.
bool EnableStaticFiles { get; set; }
Source
Gets or sets a value indicating whether static files are enabled. This is automatically enabled when MvcSupport.ControllersWithViews
or higher is used.
bool EnableStaticWebAssets { get; set; }
Source
Gets or sets a value indicating whether static web assets (from RCLs) are enabled. This is automatically enabled in the development environment.
Maps the explicit protected HTTP adapter for registered named canaries.
RouteHandlerBuilder MapAppSurfaceCanaries(this IEndpointRouteBuilder endpoints, string authorizationPolicyName, Action<AppSurfaceCanaryEndpointOptions>? configure = null)
Maps the protected named-canary route family: GET /_appsurface/canaries/{name}
evaluates one canary and GET /_appsurface/canaries
evaluates a bounded aggregate snapshot.
endpoints
authorizationPolicyName
configure
The handler builder for the fixed detail route GET /_appsurface/canaries/{name}
so the host can add ordinary endpoint conventions. The aggregate snapshot route is mapped as part of the same call but is not returned.
ArgumentNullException
endpoints
is null.ArgumentException
InvalidOperationException
The default response mode returns 200 for AppSurfaceCanaryStatus.Pass
and 503 for every other completed status. Choose AppSurfaceCanaryCompletedResponseMode.AlwaysOk
only for authenticated diagnostic consumers that always parse the JSON status. The mapper never configures authentication, authorization, retries, timeouts, triggers, or readiness behavior. Do not append anonymous metadata: the handler detects it and fails closed before name lookup or evaluator invocation. Call this method on the application root; route groups are rejected because they would relocate the fixed route.
bool TryReadMarker(HttpContext httpContext, bool required, out string? marker, out IResult? problem)
Reads the optional marker header and enforces the named-canary marker profile.
httpContext
required
marker
null
.problem
null
.
true
when the optional value is absent or one valid value of at most 256 UTF-8 bytes is present; otherwise false
. Repeated values, malformed Unicode, and control characters are rejected.
bool TryReadFreshSince(HttpContext httpContext, bool required, out DateTimeOffset? freshSince, out IResult? problem)
Reads the optional freshness header using the strict named-canary RFC 3339 profile.
httpContext
required
freshSince
null
.problem
null
.
true
when the optional value is absent or exactly one strict RFC 3339 timestamp with a Z
or numeric offset and at most seven fractional digits is present; otherwise false
.
string ToWireStatus(AppSurfaceCanaryStatus status)
Maps a defined canary status to its stable lowercase wire value.
status
The stable JSON status text.
ArgumentOutOfRangeException
status
is undefined.Reads and writes named-canary timestamps using the canonical UTC wire format.
Configures bounded execution for GET /_appsurface/canaries
.
A snapshot is current deploy evidence, not a background job or readiness probe. Cancellation remains cooperative: evaluators that ignore their token can delay the response, but they are never left running after it completes.
AppSurfaceCanarySnapshotOptions Copy()
Creates an internal immutable-at-mapping copy of these host settings.
int MaxSelectedCanaries { get; set; }
Source
Gets or sets the maximum selected canaries. The default is 64 and the supported range is 1-256.
MapAppSurfaceCanaries
throws ArgumentException
when this value is outside its supported range.
int MaxConcurrency { get; set; }
Source
Gets or sets the maximum concurrent evaluator invocations. The default is 4 and the supported range is 1-64.
MapAppSurfaceCanaries
throws ArgumentException
when this value is outside its supported range.
TimeSpan PerCheckTimeout { get; set; }
Source
Gets or sets the timeout applied to each started evaluator. The default is 10 seconds; the value must be positive and no greater than OverallTimeout
.
MapAppSurfaceCanaries
throws ArgumentException
when this constraint is violated.
TimeSpan OverallTimeout { get; set; }
Source
Gets or sets the total snapshot admission deadline. The default is 30 seconds; the value must be positive and not shorter than PerCheckTimeout
.
Reaching this deadline cancels every started evaluator. An evaluator that observes that cancellation reports ASCAN303
; a separate non-cancellation evaluator failure remains ASCAN301
. MapAppSurfaceCanaries
throws ArgumentException
when this constraint is violated.
Resolves a deterministic development port for AppSurface web hosts in development when the caller has not already supplied explicit ASP.NET Core endpoint configuration.
AppSurfaceWebDevelopmentPortResolution Resolve(string[] args, string currentDirectory, string applicationBaseDirectory, Func<string, string?> environmentReader, IEnumerable<string>? environmentVariableNames = null)
Applies a deterministic localhost --urls
fallback in development when command-line arguments, environment variables, and local appsettings files do not specify where the host should listen.
args
currentDirectory
applicationBaseDirectory
environmentReader
environmentVariableNames
A resolution describing the effective arguments. If no fallback was needed, the returned arguments match the supplied args
.
Describes the effective command-line arguments after AppSurface web development defaults have been resolved.
Args
AppliedPort
SeedPath
Configures AppSurface's explicit starter service-worker strategy.
Offline behavior is disabled by default because service workers can create stale or private-content bugs when they cache arbitrary routes. When enabled, the built-in worker caches only OfflineFallbackPath
and StaticAssetPaths
. It does not cache app navigations, authenticated pages, POST responses, or API data.
bool Enabled { get; set; }
Source
Gets or sets a value indicating whether AppSurface should map a starter service-worker endpoint.
string ServiceWorkerPath { get; set; }
Source
Gets or sets the app-root-relative service-worker endpoint path.
This compatibility property shares its effective value with PwaOptions.Worker
on the instance owned by PwaOptions
. New code should configure PwaWorkerOptions.ServiceWorkerPath
. Conflicting explicit legacy and current values fail startup.
string OfflineFallbackPath { get; set; }
Source
Gets or sets the app-root-relative offline fallback page cached by the starter service worker.
string[] StaticAssetPaths { get; set; }
Source
Gets or sets app-root-relative static asset URLs the starter service worker should cache.
Validates named-canary identifiers and snapshots registration options into internal descriptors.
void ValidateName(string name)
Validates a named-canary identifier.
name
ArgumentNullException
name
is null
.ArgumentException
name
violates the grammar or length limit.Names contain 1-128 lowercase ASCII letters or digits in dot-separated segments. Hyphens are allowed only inside a segment, never at an edge. Empty segments and consecutive dots are rejected.
bool IsValidName(string? name)
Determines whether a query name has the same grammar as a registration name.
bool IsValidTag(string? tag)
Determines whether a query tag has the same grammar as a registration tag.
AppSurfaceCanaryDescriptor CreateDescriptor(string name, Type evaluatorType, AppSurfaceCanaryRegistrationOptions options)
Validates configured metadata and creates an immutable descriptor snapshot.
name
evaluatorType
IAppSurfaceCanaryEvaluator
. options
A descriptor whose tags are deduplicated and stored in ordinal order and whose required-input flags are frozen.
ArgumentException
ASCAN101
. Represents configuration options for AppSurface's conventional browser error pages.
The default configuration keeps BrowserStatusPageMode
at BrowserStatusPageMode.Auto
, which enables conventional 401, 403, and 404 browser pages only when MVC support already includes Razor views. Apps that need the HTML status-page experience regardless of their starting MVC mode can opt into BrowserStatusPageMode.Enabled
, while API-only or custom status-code handling stacks should use BrowserStatusPageMode.Disabled
. Conventional production 500 pages are separate and always require an explicit call to UseConventionalExceptionPage
.
void UseConventionalBrowserStatusPages()
Explicitly enables AppSurface's conventional browser status pages.
Use this when an app must always render the conventional HTML 401, 403, and 404 pages. AppSurface may effectively require controllers with views at startup so the configured Razor pages can execute.
void DisableBrowserStatusPages()
Explicitly disables AppSurface's conventional browser status pages.
Use this for APIs, custom status-code middleware, or any app that wants to keep conventional browser status routes and handling out of the pipeline even when MVC view support is available.
void UseConventionalExceptionPage()
Explicitly enables AppSurface's conventional production exception page.
Use this for browser-facing apps that want AppSurface to own the production 500 page through ASP.NET Core exception handling. The page renders only safe generic copy plus a request id, and AppSurface leaves Development behavior alone so developer exception diagnostics can remain active during local work. API-only apps or applications with custom exception middleware should leave this disabled and register their own handling before application endpoints.
void DisableConventionalExceptionPage()
Explicitly disables AppSurface's conventional production exception page.
Use this when a module enables the conventional exception page but the application host needs to supply a different exception-handling policy, such as JSON problem details, tenant-specific pages, or telemetry-first middleware.
bool AreConventionalBrowserStatusPagesEnabled(MvcSupport mvcSupportLevel)
Determines whether AppSurface should enable conventional browser status pages for the supplied MVC support level.
mvcSupportLevel
true
when the conventional page should be active; otherwise, false
.
This helper is used by AppSurface startup after module and app options are applied. In BrowserStatusPageMode.Auto
, the feature only turns on when MVC already includes views. In BrowserStatusPageMode.Enabled
, the feature is active regardless of the incoming MVC level because startup may upgrade the app to support Razor views.
ErrorPagesOptions Default { get; }
Source
Gets a default instance of ErrorPagesOptions
with BrowserStatusPageMode.Auto
.
BrowserStatusPageMode BrowserStatusPageMode { get; set; }
Source
Gets or sets the conventional browser status page behavior for the application.
BrowserStatusPageMode.Auto
is the default and turns the feature on only when the app's MVC support reaches MvcSupport.ControllersWithViews
. Choosing BrowserStatusPageMode.Enabled
can cause AppSurface startup to upgrade MVC support so the conventional Razor views can render. Choosing BrowserStatusPageMode.Disabled
prevents the reserved framework routes and browser-oriented status handling from activating.
bool ConventionalExceptionPageEnabled { get; set; }
Source
Gets or sets a value indicating whether AppSurface should render the conventional production exception page.
The default is false
so apps do not accidentally replace an existing exception-handling policy. Set this through UseConventionalExceptionPage
when browser users should see a safe, generic HTML 500 page for unhandled exceptions in non-development environments. AppSurface uses ASP.NET Core's exception-handler middleware for this feature; status-code pages cannot catch thrown exceptions.
Configures the shared AppSurface service-worker and registration-helper endpoints.
The worker is mapped when either PwaOfflineOptions.Enabled
or PwaPushOptions.Enabled
is enabled. Worker activation is independent from install-manifest metadata.
string ServiceWorkerPath { get; set; }
Source
Gets or sets the app-root-relative generated service-worker endpoint path.
The default is /service-worker.js
. On the instance owned by PwaOptions
, this setting is compatible with PwaOfflineOptions.ServiceWorkerPath
. Configuring both properties with different values fails startup instead of depending on configuration-provider assignment order. Percent escapes are rejected because this value owns a generated endpoint.
string RegistrationHelperPath { get; set; }
Source
Gets or sets the app-root-relative endpoint for the inert registration helper.
The default is /_appsurface/pwa/register.js
. The helper is mapped only when push is enabled. Percent escapes are rejected because this value owns a generated endpoint.
bool HasServiceWorkerPathConflict { get; }
Source
Gets a value indicating whether legacy and current worker path properties were assigned conflicting values.
Registers application-owned named canary evaluators and immutable metadata.
IServiceCollection AddAppSurfaceCanary<TEvaluator>(this IServiceCollection services, string name, Action<AppSurfaceCanaryRegistrationOptions>? configure = null)
Registers one typed evaluator under an exact lowercase, dot-separated canary name.
TEvaluator
services
name
configure
The original service collection.
ArgumentNullException
services
or name
is null.ArgumentException
Registration does not expose an HTTP endpoint. Call AppSurfaceCanaryEndpointRouteBuilderExtensions.MapAppSurfaceCanaries
explicitly with a host-owned authorization policy. The evaluator is added as transient only when the host has not already registered the concrete type, so singleton, scoped, and transient overrides are supported.
Defines the conventional paths used by AppSurface's built-in browser-friendly status page handling.
AppSurface owns browser status pages for 401, 403, and 404 responses in this release. Production exception pages, including conventional 500 handling, are intentionally separate because ASP.NET Core routes exceptions through exception-handling middleware instead of status-code pages.
string GetAppViewPath(int statusCode)
Formats the conventional app override view path for the supplied HTTP status code.
statusCode
The app/shared Razor view path produced from AppViewPathFormat
.
This helper does not validate support. Callers that accept arbitrary status codes should use BrowserStatusPageDescriptor.TryGet(int, out BrowserStatusPageDescriptor)
before rendering.
string GetReservedRoute(int statusCode)
Formats the framework-reserved preview route for the supplied HTTP status code.
statusCode
The reserved route produced from ReservedRouteFormat
.
The returned path is for framework middleware, direct preview, and tooling such as static export. It should not be exposed as an application-owned route.
Provides the default AppSurface Web platform probe endpoint paths.
Declares one icon entry emitted into the generated PWA manifest and optional page head metadata.
Source
must be an app-root-relative path such as /icons/app-192.png
. AppSurface validates the declared Sizes
token values and exposes them in diagnostics, but it does not decode image dimensions at runtime. Use appsurface pwa verify
to prove icon URLs are reachable and decode PNG dimensions from a running app.
string Source { get; set; }
Source
Gets or sets the app-root-relative icon URL.
string Sizes { get; set; }
Source
Gets or sets the manifest size token list, for example 192x192
or 192x192 512x512
.
string Type { get; set; }
Source
Gets or sets the icon content type. Defaults to image/png
.
string? Purpose { get; set; }
Source
Gets or sets the optional manifest purpose, for example any
or maskable
.
string Read(Assembly assembly, string fileName)
Reads a named PWA resource from an assembly.
assembly
fileName
The UTF-8 resource contents.
InvalidOperationException
string WorkerOffline { get; }
Source
Gets the optional offline capability source.
string WorkerPush { get; }
Source
Gets the default version-1 push and notification-click source.
string WorkerCustomHandler { get; }
Source
Gets the contained custom push-handler import source.
string RegistrationHelper { get; }
Source
Gets the inert browser registration-helper source.
string BadgingFactory { get; }
Source
Gets the canonical badging installer factory shared by page and worker wrappers.
string BadgingHelper { get; }
Source
Gets the inert browser badging-helper source.
string WorkerBadging { get; }
Source
Gets the generated-worker badging adapter source.
string PathValidationVectors { get; }
Source
Gets the shared C# and JavaScript path-validation vectors.
string RegistrationHelperVersion { get; }
Source
Gets the content-derived cache version for the registration helper.
string BadgingHelperVersion { get; }
Source
Gets the content-derived cache version for the badging page helper.
Marks the single framework-owned endpoint in the reserved named-canary namespace.
AppSurfaceCanaryRouteMetadata Instance { get; }
Source
Gets the shared marker instance attached to the package-owned endpoint.
Runs one transport-neutral named-canary lookup and evaluation in the current service scope.
ValueTask<AppSurfaceCanaryEvaluationOutcome> EvaluateAsync(string name, string? marker, DateTimeOffset? freshSince, CancellationToken cancellationToken)
Looks up and evaluates one registered name without applying HTTP status mapping.
name
marker
freshSince
cancellationToken
A not-found outcome or the evaluator result wrapped as a completed outcome.
ValueTask<AppSurfaceCanaryResult> EvaluateAsync(AppSurfaceCanaryDescriptor descriptor, string? marker, DateTimeOffset? freshSince, CancellationToken cancellationToken)
Resolves and invokes the evaluator represented by a known descriptor in the current service scope.
descriptor
marker
freshSince
cancellationToken
The non-null evaluator result, including any validated optional evidence.
ArgumentNullException
descriptor
is null
.InvalidOperationException
null
or includes a detail key absent from the descriptor's declared allowed keys. bool TryGetDescriptor(string name, out AppSurfaceCanaryDescriptor descriptor)
Attempts exact ordinal lookup without resolving an evaluator.
name
descriptor
true
when the name is registered; otherwise false
.
Represents either an exact-name miss or a completed transport-neutral evaluation.
AppSurfaceCanaryEvaluationOutcome Completed(AppSurfaceCanaryResult result)
Creates an outcome for a non-null completed evaluator result.
result
A found outcome containing result
.
AppSurfaceCanaryEvaluationOutcome NotFound { get; }
Source
Gets the shared exact-name miss outcome.
bool Found { get; }
Source
Gets a value indicating whether a registered descriptor was found.
AppSurfaceCanaryResult? Result { get; }
Source
Gets the completed result, or null
for NotFound
.
Configures the opt-in AppSurface browser adapter for the Progressive Web App Badging API.
Badging is a write-only progressive enhancement. AppSurface validates calls and normalizes value-free outcomes, but it does not own the badge count, request permission, persist state, or prove that an operating system displayed a badge. Applications must keep an accessible in-app representation of the same attention state.
bool Enabled { get; set; }
Source
Gets or sets a value indicating whether AppSurface should expose the page badging helper and compose the same adapter into an already-enabled AppSurface worker.
Enabling badging alone does not create a service worker or enable static-file middleware.
string HelperPath { get; set; }
Source
Gets or sets the app-root-relative generated page-helper endpoint path.
The generated endpoint is served only when Enabled
is enabled. Paths reject percent escapes and other ambiguous URL forms so routing, emitted head markup, and diagnostics use one representation.
Stores an immutable named-canary registration without resolving its evaluator.
string Name { get; }
Source
Gets the validated exact registration name.
string DisplayName { get; }
Source
Gets the nonblank adopter-facing display name.
string? Description { get; }
Source
Gets the optional description.
IReadOnlySet<string> Tags { get; }
Source
Gets the immutable ordinal-sorted tag snapshot.
bool MarkerRequired { get; }
Source
Gets a value indicating whether the marker input is required.
bool FreshSinceRequired { get; }
Source
Gets a value indicating whether the freshness boundary is required.
IReadOnlySet<string> AllowedDetailKeys { get; }
Source
Gets the immutable ordinal set of detail keys this evaluator may return.
Type EvaluatorType { get; }
Source
Gets the concrete evaluator service type resolved for each evaluation.
Configures independent AppSurface Progressive Web App install, offline, push-worker, and badging capabilities.
Set Enabled
to true
when AppSurface should emit and serve install metadata for a web app. Required metadata mirrors the browser-facing manifest fields that make install posture understandable: names, start URL, scope, display mode, theme/background colors, and 192x192 plus 512x512 icons. AppSurface maps diagnostics separately from install metadata so production apps can hide diagnostics while still serving the manifest. Offline and push capabilities activate one shared worker without requiring install metadata. Badging exposes a page helper independently and joins that worker only when another capability already activates it.
PwaOptions Default { get; }
Source
Gets a default disabled PWA options instance.
bool Enabled { get; set; }
Source
Gets or sets a value indicating whether AppSurface should map PWA install-manifest metadata endpoints.
This setting does not suppress Offline
or Push
when either capability is enabled.
string ManifestPath { get; set; }
Source
Gets or sets the app-root-relative generated manifest endpoint path.
Generated endpoint paths reject percent escapes so routing and emitted metadata use one representation. This path remains validated and appears PathBase-adjusted in diagnostics whenever any PWA surface is active, although the manifest endpoint is mapped only when Enabled
is enabled.
PwaDiagnosticEndpointExposure DiagnosticsExposure { get; set; }
Source
Gets or sets when the PWA diagnostics endpoint should be mapped.
string DiagnosticsPath { get; set; }
Source
Gets or sets the app-root-relative diagnostics endpoint path.
Generated endpoint paths reject percent escapes so routing and emitted metadata use one representation.
string Name { get; set; }
Source
Gets or sets the full application name emitted into the manifest.
string ShortName { get; set; }
Source
Gets or sets the short application name emitted into the manifest.
string StartUrl { get; set; }
Source
Gets or sets the app-root-relative start URL emitted into the manifest.
string Scope { get; set; }
Source
Gets or sets the app-root-relative manifest and service-worker scope.
The default is /
. The scope is validated whenever install metadata or a worker capability is active. Browsers use raw URL-prefix matching, so /app
also covers /application
; use /app/
when a path-segment boundary is intended.
PwaDisplayMode Display { get; set; }
Source
Gets or sets the display mode emitted into the manifest.
string ThemeColor { get; set; }
Source
Gets or sets the manifest and browser theme color as a CSS hex color.
string BackgroundColor { get; set; }
Source
Gets or sets the manifest background color as a CSS hex color.
IList<PwaIcon> Icons { get; }
Source
Gets or sets the icon entries emitted into the generated manifest.
PwaWorkerOptions Worker { get; }
Source
Gets shared service-worker and registration-helper endpoint settings.
PwaOfflineOptions Offline { get; }
Source
Gets explicit offline strategy settings.
PwaPushOptions Push { get; }
Source
Gets opt-in Web Push worker settings.
PwaBadgingOptions Badging { get; }
Source
Gets opt-in application-icon badging settings.
bool IsWorkerEnabled { get; }
Source
Gets whether at least one capability requires the shared service worker.
bool HasAnySurfaceEnabled { get; }
Source
Gets whether AppSurface should validate and map any PWA surface.
bool HasAnyGeneratedScriptRoute { get; }
Source
Gets whether at least one active capability maps a generated JavaScript route.
bool RequiresStaticFileMiddleware { get; }
Source
Gets whether the configured PWA surfaces require AppSurface to enable static-file middleware.
Install metadata preserves the existing static-icon behavior, offline support may reference static fallback assets, and a custom push handler may be deployed from the web root. The generated default push worker and registration helper are endpoints and do not require static-file middleware.
Represents the model passed to AppSurface's conventional production exception view.
StatusCode
RequestId
This model intentionally excludes exception details, request headers, cookies, route values, and form fields. Production error pages should help users recover and help operators correlate logs without disclosing request internals or implementation details.
Defines a module that exposes web-specific configuration, endpoints, and middleware.
void ConfigureWebOptions(StartupContext context, WebOptions options)
Configures WebOptions
for the application, such as MVC, CORS, and static files.
context
options
void ConfigureEndpoints(StartupContext context, IEndpointRouteBuilder endpoints)
Allows the module to configure endpoint routes for the application.
context
endpoints
void ConfigureWebApplication(StartupContext context, IApplicationBuilder app)
Configure the ASP.NET Core request pipeline for this module.
context
app
void ConfigureEndpointAwareMiddleware(StartupContext context, IApplicationBuilder app)
Configures middleware that can inspect endpoint routing metadata before endpoints execute.
context
app
AppSurface invokes this hook after UseRouting
and AppSurface-managed CORS middleware, and before UseEndpoints
. Middleware registered here can inspect HttpContext.GetEndpoint()
at request time, but unmatched requests can still have no selected endpoint. Root or host integration modules should register global authentication and authorization middleware here before feature modules add endpoint-aware middleware they own. Do not call UseRouting
, UseCors
, UseEndpoints
, or map endpoints from this hook; use ConfigureEndpoints
for endpoint mapping.
bool IncludeAsApplicationPart { get; }
Source
Gets a value indicating whether this module's assembly should be searched for MVC application parts (controllers, views, etc.). Defaults to false.
Coordinates the process-wide single mapping claim and startup validator activation.
bool TryClaim(ICollection<Microsoft.AspNetCore.Routing.EndpointDataSource> dataSources)
Atomically claims named-canary mapping for one endpoint data-source collection.
dataSources
true
for the first claim; otherwise false
without replacing the collection captured by the first caller.
ArgumentNullException
dataSources
is null
.ICollection<Microsoft.AspNetCore.Routing.EndpointDataSource>? DataSources { get; }
Source
Gets the endpoint data-source collection captured by the first successful mapping claim, or null
before named canaries are mapped.
Classifies evaluator failures that package-owned HTTP and snapshot adapters can convert into safe failures.
bool IsNonFatal(Exception exception)
Determines whether an evaluator failure can be converted into a safe package-owned failure response.
exception
false
for fatal process/runtime exceptions; otherwise true
.
Contains the validated inputs for one named canary evaluation.
string Name { get; }
Source
Gets the exact registered canary name.
string? Marker { get; }
Source
Gets the optional opaque deploy marker exactly as supplied to this context. The HTTP adapter preserves the value delivered by ASP.NET Core; HTTP servers and clients may normalize leading or trailing field-value whitespace.
DateTimeOffset? FreshSince { get; }
Source
Gets the optional freshness boundary normalized by the HTTP adapter to UTC.
Validates the final endpoint pipeline before server startup, rejecting a relocated framework route or host-owned routes that could shadow or overlap the reserved named-canary namespace.
Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
Appends reserved-route validation after the host finishes composing its pipeline.
next
A pipeline action that invokes next
before validating final endpoints.
ArgumentNullException
next
is null
.void Validate()
Validates that the framework route retained its fixed location and that no host route overlaps the reserved named-canary namespace. The method is inactive before mapping captures endpoint data sources.
InvalidOperationException
string Normalize(string? route)
Normalizes a defensive route value for ordinal reserved-namespace comparison.
route
A leading-slash route with trailing slashes removed, or /
for a blank value.
Evaluates application-owned proof for one registered named canary.
Evaluators inspect existing proof exactly once per request. They should not trigger synthetic work, retry, poll, or change application readiness. The caller owns those orchestration decisions.
ValueTask<AppSurfaceCanaryResult> EvaluateAsync(AppSurfaceCanaryEvaluationContext context, CancellationToken cancellationToken)
Evaluates current proof for a named canary.
context
cancellationToken
The current canary status plus any optional validated, bounded evidence.
Resolves app-root-relative PWA paths beneath the current request path base.
string Add(PathString pathBase, string path)
Prepends pathBase
to the app-root-relative path
.
pathBase
path
The path resolved beneath pathBase
.
void ThrowIfInvalid(PwaOptions options, IFileProvider webRootFileProvider)
Rejects generated worker/helper routes that static-file middleware would serve first.
options
webRootFileProvider
Configures opt-in Web Push event handling in the shared AppSurface service worker.
Enabling push maps worker plumbing and the explicit registration helper. It does not request notification permission, create a push subscription, store subscriber identity, or send notifications.
bool Enabled { get; set; }
Source
Gets or sets a value indicating whether the generated worker should support push events.
string? HandlerScriptPath { get; set; }
Source
Gets or sets an optional app-root-relative classic worker script that owns push and notification-click events.
Leave this value null
to use AppSurface's strict version-1 notification adapter. When set, AppSurface imports the script with importScripts()
and does not emit its default push or click listeners. AppSurface contains a load or top-level evaluation failure with ASPWAJS030
so shared lifecycle and offline behavior remain available. The application should still deploy this asset atomically. Browser script evaluation is not transactional, so a handler must finish validation and initialization before registering listeners that would otherwise survive a later top-level exception.
Provides defaults for AppSurface configuration-audit HTTP diagnostics endpoints.
Use DefaultRoute
when a host wants the standard opt-in AppSurface diagnostics path. Prefer a custom route with AppSurfaceConfigAuditDiagnosticsEndpointRouteBuilderExtensions.MapAppSurfaceConfigAuditDiagnostics(Microsoft.AspNetCore.Routing.IEndpointRouteBuilder, string, string)
when the deployment already reserves this prefix or needs diagnostics to live under a host-owned operations path. Configuration audit output is support-sensitive even after value redaction, and the mapper hides the endpoint from API Explorer/OpenAPI by default instead of treating it as a public discovery surface.
Configures AppSurface Web platform health and readiness probe endpoints.
Enable this surface when container or service-platform probes will consume it. The endpoints use ASP.NET Core health checks. HealthPath
runs all checks; ReadyPath
runs checks tagged with ReadyTag
. If no checks are tagged for readiness, the readiness endpoint reports healthy once the app has started. When disabled, AppSurface does not register health-check services or map probe endpoints.
HealthOptions Default { get; }
Source
Gets a default disabled health options instance.
bool Enabled { get; set; }
Source
Gets or sets a value indicating whether AppSurface should map platform health and readiness endpoints.
The default is false
. Enable probes only when deployment or monitoring infrastructure consumes them; enabling registers ASP.NET Core health-check services and maps both configured endpoints.
string HealthPath { get; set; }
Source
Gets or sets the app-root-relative endpoint path that runs all registered ASP.NET Core health checks.
string ReadyPath { get; set; }
Source
Gets or sets the app-root-relative endpoint path that runs readiness-tagged ASP.NET Core health checks.
string ReadyTag { get; set; }
Source
Gets or sets the health-check tag used to select checks for the readiness endpoint.
Resolves and renders AppSurface's conventional browser status page views.
View resolution prefers the status-specific app/shared Razor Class Library path first, for example ~/Views/Shared/403.cshtml
. If that view is missing, the renderer falls back to AppSurface's shared framework view. Resolved paths are cached per status code so a 401 override cannot accidentally satisfy a later 403 or 404 render.
void ValidateConfiguredViews()
Performs eager validation of all configured conventional browser status page views.
Call this during startup to fail fast if neither the conventional app/shared view nor the framework fallback view can be resolved for any supported status. Runtime rendering also resolves lazily, but this method turns a missing view into a predictable startup error instead of a request-time failure. Validation also warms and pins the runtime view-path cache by resolving every BrowserStatusPageDescriptor.Supported
entry. If an app adds or removes status page views after this method runs, the startup-selected app or framework fallback path remains in use for the process lifetime.
Task RenderAsync(HttpContext httpContext)
Renders the resolved conventional browser status page view into the current HTTP response.
httpContext
The rendered model is always a BrowserStatusPageModel
. Its status defaults to 404 when the request is a direct render without a re-execute feature or reserved-route status code. This method does not change HttpResponse.StatusCode
itself, which lets direct previews keep their existing 200 response and re-executed status requests preserve their original HTTP status. CreateModel(HttpContext)
can receive an explicit status from re-execution metadata or the reserved route. That status must be supported by BrowserStatusPageDescriptor
; otherwise this method throws instead of rendering a mismatched page for the existing HttpResponse.StatusCode
.
Resolves and renders AppSurface's conventional production exception page view.
View resolution prefers ConventionalExceptionPageDefaults.AppViewPath
first so apps and shared Razor Class Libraries can override the page conventionally. If that view is missing, the renderer falls back to ConventionalExceptionPageDefaults.FrameworkFallbackViewPath
. The rendered model is deliberately small and safe: status code plus request id only.
void ValidateConfiguredViews()
Performs eager validation of the configured conventional 500 view.
Call this during startup to fail fast in production-like environments if neither the conventional app/shared view nor the framework fallback view can be resolved. Runtime rendering also resolves lazily, but this method turns a missing view into a predictable startup error instead of a request-time failure.
Task RenderAsync(HttpContext httpContext)
Renders the resolved conventional 500 view into the current HTTP response.
httpContext
This method sets the response status to 500 and passes only ExceptionPageModel
to the view. It intentionally does not inspect IExceptionHandlerFeature
or request data, so exception messages, stack traces, headers, cookies, route values, and form values cannot be disclosed through the default model.
Represents the immutable result of one named canary evaluation.
AppSurfaceCanaryStatus Status { get; }
Source
Gets the current canary status.
DateTimeOffset? ObservedAt { get; }
Source
Gets the optional proof-observation time normalized to UTC.
int? MatchedCount { get; }
Source
Gets the optional non-negative count of matching proofs.
string? ReasonCode { get; }
Source
Gets the optional stable machine-readable response reason: 1-64 lowercase ASCII letters or digits separated by internal hyphens, with an alphanumeric first and last character.
string? Summary { get; }
Source
Gets optional response-only operator-safe explanatory text that is nonblank, at most 256 UTF-8 bytes, well-formed Unicode, and free of Unicode control ( Cc
) scalars.
string? CorrelationId { get; }
Source
Gets the optional response-only non-secret correlation identifier: 1-128 ASCII letters, digits, periods, underscores, colons, or hyphens, with an alphanumeric first and last character.
IReadOnlyDictionary<string, string> Details { get; }
Source
Gets up to 16 immutable, ordinal-sorted response-only details. Keys use 1-64 character lowercase dot-separated segments; values are nonblank, at most 128 UTF-8 bytes, well-formed Unicode, and free of Unicode control ( Cc
) scalars.
Configures the HTTP adapter for named canary evaluations.
AppSurfaceCanaryCompletedResponseMode CompletedResponseMode { get; set; }
Source
Gets or sets completed-result HTTP mapping. The default is AppSurfaceCanaryCompletedResponseMode.StatusCode
.
AppSurfaceCanarySnapshotOptions Snapshot { get; }
Source
Gets the bounded aggregate snapshot settings. Defaults are safe for deploy-operator requests.
Provides a base implementation for a web-based AppSurfaceStartup{TModule}
that handles MVC, CORS, and static file configuration based on registered IAppSurfaceWebModule
instances.
TModule
IAppSurfaceWebModule
for the application.WebStartup<TModule> WithOptions(Action<WebOptions>? configureOptions = null)
Registers an optional callback to customize WebOptions and enables fluent chaining.
configureOptions
The same WebStartup{TModule}
instance to support fluent configuration.
Task RunAsync(string[] args)
Starts the web host with AppSurface Web's deterministic development-port fallback when the caller has not explicitly configured an endpoint through command-line arguments, environment variables, or appsettings.
args
A task that completes when the web host run exits.
AppSurfaceWebDevelopmentPortResolution ResolveDevelopmentPortDefaults(string[] args)
Resolves the effective command-line arguments before the web host starts.
args
The resolved startup arguments and any deterministic development-port metadata.
Task RunResolvedAsync(string[] args)
Runs the base host startup path with arguments after AppSurface Web development defaults have been resolved.
args
A task that completes when the web host run exits.
void BuildModules(StartupContext context)
Collects and caches all IAppSurfaceWebModule instances found in the provided startup context. This method is idempotent.
context
This method is idempotent; subsequent calls have no effect once modules are built.
void BuildWebOptions(StartupContext context)
Initializes and caches WebOptions by applying configuration from discovered modules and the optional custom callback; enables static file support when MVC is configured for controllers with views.
context
This method is idempotent; subsequent calls have no effect once options are built.
void ConfigureServicesForAppType(StartupContext context, IServiceCollection services)
Configures services required for the web application: registers MVC application parts from the entry assembly and enabled web modules, and adds a CORS policy when CORS is enabled.
context
services
InvalidOperationException
*
.IHostBuilder ConfigureBuilderForAppType(StartupContext context, IHostBuilder builder)
Configures the provided host builder with web host defaults and registers the application's web initialization pipeline.
context
builder
The same IHostBuilder
configured with web host defaults and the application's initialization pipeline.
void InitializeWebApplication(StartupContext context, IApplicationBuilder app)
Configures the application's middleware pipeline and endpoint routing for the web application.
context
app
Represents the model passed to AppSurface's conventional browser status page view.
StatusCode
OriginalPath
OriginalQueryString
The framework renderer normalizes missing or malformed route status values to 404 before creating the default model, but explicit status values must be supported by the built-in browser status page descriptors. Custom producers should pass only status codes their view understands. OriginalPath
and OriginalQueryString
are null for direct preview requests and can also be absent when upstream middleware strips or replaces status-code re-execution metadata. Status-page views should prefer this model for user-facing recovery copy because it captures the original failed request after AppSurface re-executes the framework route. Read HttpContext.Request
only for current-request concerns such as URL generation; during re-execution it points at the reserved framework route. Treat the query string as display-only metadata, not as authorization or security input, and do not assume the path has a trailing slash or app-specific normalization.
Provides immutable ordinal lookup for registered named canaries.
bool TryGet(string name, out AppSurfaceCanaryDescriptor descriptor)
Attempts exact ordinal lookup of a registered descriptor.
name
descriptor
true
when the name is registered; otherwise false
.
bool ContainsAllNames(IReadOnlyCollection<string> names)
Determines whether every exact selector name is registered without resolving evaluators.
IReadOnlyList<AppSurfaceCanaryDescriptor> OrderedDescriptors { get; }
Source
Gets the ordinal descriptor snapshot without resolving evaluators.
Provides optional, privacy-safe server-known evidence about the configured AppSurface Web Push rail.
Implementations must return only the fixed PwaPushReadiness
evidence. They must not expose key material, routes, callback values, subscription values, or provider exception details.
PwaPushReadiness? GetReadiness()
Gets the current privacy-safe Web Push readiness evidence, or null
when unavailable.
The fixed safe evidence record, or null
.
Contains the fixed privacy-safe facts that Web may publish in PWA diagnostics.
ActiveVapidKeyId
PublicKeyFingerprint
RouteMapped
Runs a selected named-canary snapshot with bounded concurrent, cooperative evaluation.
bool TrySelect(IReadOnlyCollection<string> names, IReadOnlyCollection<string> tags, int maximum, out IReadOnlyList<AppSurfaceCanaryDescriptor> selected)
Selects registered descriptors by exact name or tag and reports whether the selected set fits the supplied limit.
names
tags
maximum
selected
false
because the selection exceeded maximum
.
true
when selected
contains no more than maximum
descriptors; otherwise false
. Empty names
and tags
select every registered canary.
bool ContainsAllNames(IReadOnlyCollection<string> names)
Determines whether every exact name selector is registered without resolving evaluators.
names
true
when every name is registered; otherwise false
.
Task<AppSurfaceCanarySnapshotOutcome> EvaluateAsync(IReadOnlyList<AppSurfaceCanaryDescriptor> descriptors, string? marker, DateTimeOffset? freshSince, AppSurfaceCanarySnapshotOptions options, CancellationToken requestAborted)
Evaluates the supplied ordinal descriptor selection with the configured bounded snapshot policy.
descriptors
marker
freshSince
options
requestAborted
A settled aggregate containing one privacy-safe item for every supplied descriptor.
OperationCanceledException
requestAborted
was canceled.The method waits for every started evaluator to settle. An evaluator that ignores cooperative cancellation delays the response but cannot contribute a successful result after either deadline expires.
Represents the settled, ordered result of one bounded snapshot request.
IReadOnlyList<AppSurfaceCanarySnapshotItem> Items { get; }
Source
Gets one settled privacy-safe item for each selected descriptor, in ordinal order.
bool OverallTimedOut { get; }
Source
Gets whether the overall deadline timed out a started or queued evaluator.
bool Ready { get; }
Source
Gets whether every selected item completed successfully before the overall deadline.
Represents one privacy-safe aggregate item outcome.
AppSurfaceCanarySnapshotItem Completed(string name, AppSurfaceCanaryResult result, double elapsedMilliseconds)
Creates a completed item containing the evaluator result.
AppSurfaceCanarySnapshotItem Failed(string name)
Creates a redacted evaluator-failure item.
AppSurfaceCanarySnapshotItem PerCheckTimedOut(string name)
Creates an item that exceeded its per-check deadline.
AppSurfaceCanarySnapshotItem OverallTimedOut(string name)
Creates a started item that was canceled by the overall deadline.
AppSurfaceCanarySnapshotItem NotStarted(string name)
Creates an item that was never admitted before the overall deadline.
string Name { get; }
Source
Gets the exact registered canary name.
AppSurfaceCanarySnapshotItemState State { get; }
Source
Gets the typed settlement state used for internal aggregation.
string Outcome { get; }
Source
Gets the stable response-envelope outcome projected from State
.
string? ReasonCode { get; }
Source
Gets the safe non-completed diagnostic projected from State
, when applicable.
AppSurfaceCanaryResult? Result { get; }
Source
Gets the completed evaluator result; otherwise null
.
double? ElapsedMilliseconds { get; }
Source
Gets the completed evaluator elapsed time in milliseconds; otherwise null
.
bool BoundedByOverallDeadline { get; }
Source
Gets whether the overall deadline settled this item before it completed.
bool Ready { get; }
Source
Gets whether the item completed with a passing evaluator result.
Provides the conventional named-canary route contract.
Provides health-check tags understood by AppSurface Web's platform probe endpoints.
Builds operator-facing details for AppSurface Web startup watchdog failures.
The diagnostic intentionally keeps to process and host-shape facts that are safe to log: sandbox markers, startup phase, directories, static-asset mode, and endpoint-shaped command-line arguments. It avoids inspecting arbitrary app configuration values, which may contain secrets.
AppSurfaceWebStartupTimeoutDiagnostic Create(TimeSpan startupTimeout, string startupPhase, string currentDirectory, string baseDirectory, bool staticWebAssetsEnabled, IReadOnlyList<string> startupArgs, Func<string, string?> environmentReader)
Creates a startup-timeout diagnostic from the current process environment.
startupTimeout
startupPhase
currentDirectory
baseDirectory
staticWebAssetsEnabled
startupArgs
environmentReader
A diagnostic object suitable for structured logging and tests.
bool SandboxDetected { get; }
Source
Gets a value indicating whether the process environment contains a known sandbox marker.
string SandboxSummary { get; }
Source
Gets a display-safe summary of detected sandbox markers.
string RecommendedAction { get; }
Source
Gets the concrete next step operators should try first.
string StartupArgsSummary { get; }
Source
Gets endpoint-related command-line arguments rendered for diagnostics.
string BuildServiceWorkerScript(HttpContext httpContext, PwaOptions options)
Composes the exact generated worker from a JSON configuration and capability-specific embedded sources.
httpContext
options
The complete classic service-worker source.
Represents privacy-safe, server-known PWA posture for diagnostics and CLI compatibility.
Enabled
ManifestPath
OfflineEnabled
ConfiguredServiceWorkerPath
ServiceWorkerPath
OfflineFallbackPath
WorkerEnabled
WorkerPath
PushEnabled
WorkerScope
RegistrationHelperPath
BadgingEnabled
BadgingHelperPath
PushReadiness
Diagnostics
Defines the JSON-safe configuration consumed by embedded worker fragments.
OfflineEnabled
CachePrefix
CacheName
LegacyCacheNames
StaticAssets
OfflineFallback
PathBase
Scope
HandlerScriptPath
Describes one built-in browser status page that AppSurface can preview, re-execute, and render.
StatusCode
AppViewPath
ReservedRoute
Title
Eyebrow
Heading
Description
PrimaryActionText
Descriptors are internal framework metadata for the current built-in status set: 401, 403, and 404. Use TryGet(int, out BrowserStatusPageDescriptor)
before routing or rendering arbitrary status codes; unsupported codes should not be re-executed through the browser status page pipeline.
bool TryGet(int statusCode, out BrowserStatusPageDescriptor? descriptor)
Attempts to resolve a built-in browser status page descriptor for an HTTP status code.
statusCode
descriptor
true
, the descriptor for statusCode
; otherwise null
.
true
for supported status codes 401, 403, and 404; otherwise false
.
Unknown status codes are intentionally rejected so production exception pages and future status families can be designed separately instead of accidentally using the 401/403/404 browser-page contract.
string FrameworkFallbackViewPath { get; }
Source
Gets the shared framework fallback view path used when AppViewPath
cannot be resolved.
The fallback is shared across all supported statuses. App and shared Razor Class Library overrides remain status-specific through AppViewPath
.
IReadOnlyList<BrowserStatusPageDescriptor> Supported { get; }
Source
Gets all built-in browser status page descriptors in the order AppSurface validates them.
This list is the built-in set for the current release, not a promise that every browser-relevant status is supported. Callers should use TryGet(int, out BrowserStatusPageDescriptor)
for lookup instead of assuming a status code is present.
Evaluates whether a resolved PWA start URL path falls within a resolved manifest scope path.
The matcher centralizes the browser-style prefix contract used by both AppSurface Web startup validation and the AppSurface CLI verifier. Browser service-worker and manifest scopes use raw URL-path prefix matching. Applications that require a segment boundary should end a non-root scope in /
.
bool IsPathWithinScope(string path, string scope)
Returns a value indicating whether path
is within scope
.
path
scope
true
when path
is covered by scope
.
Configures bounded operator evidence for one named-canary result.
The result snapshots these values after the callback completes. Text supplied here is returned only from the protected named-canary endpoint; AppSurface bounds and validates its shape but does not classify or redact it. Never include secrets, personal data, provider payloads, URLs, prompts, source text, or private generated content.
void AddDetail(string key, string value)
Adds one declared, response-only detail value.
key
value
ArgumentNullException
key
or value
is null.ArgumentException
InvalidOperationException
The key must also appear in AppSurfaceCanaryRegistrationOptions.AllowedDetailKeys
for the same canary. That registration-specific check occurs after evaluation and fails closed as ASCAN301
.
DateTimeOffset? ObservedAt { get; set; }
Source
Gets or sets the optional time at which the evaluator observed its proof.
The value is normalized to UTC when the result is created. No default is inferred.
int? MatchedCount { get; set; }
Source
Gets or sets an optional non-negative count of matching proofs.
string? ReasonCode { get; set; }
Source
Gets or sets an optional stable machine-readable reason code.
A reason code is 1-64 lowercase ASCII letters, digits, or internal hyphens and must start and end with a letter or digit. It is response-only and is intended for machine branching.
string? Summary { get; set; }
Source
Gets or sets optional operator-safe explanatory text of at most 256 UTF-8 bytes.
Blank text, malformed Unicode, and Unicode control scalars are rejected.
string? CorrelationId { get; set; }
Source
Gets or sets an optional non-secret correlation identifier.
The identifier is 1-128 ASCII characters from letters, digits, period, underscore, colon, and hyphen, and it must start and end with a letter or digit. It is not added to completion logs.
Validates intrinsic named-canary result evidence.
Provides the fixed request-header names used by named canary endpoints.
Defines the conventional paths used by AppSurface's built-in browser-friendly production 500 handling.
Represents configuration options for the web application, including MVC, CORS, and static file settings.
MvcOptions Mvc { get; set; }
Source
Gets or sets MVC-specific configuration options, such as support levels and custom MVC configuration.
CorsOptions Cors { get; set; }
Source
Gets or sets CORS configuration options for defining cross-origin resource sharing policies.
StaticFilesOptions StaticFiles { get; set; }
Source
Gets or sets configuration options for serving static files within the web application.
ErrorPagesOptions Errors { get; set; }
Source
Gets or sets configuration options for conventional framework browser status pages.
The default value is ErrorPagesOptions.Default
, which leaves browser status pages in BrowserStatusPageMode.Auto
. In that mode, AppSurface only enables the conventional browser 401, 403, and 404 experience when MVC support already includes views. Use explicit modes when an app must always force or always suppress the conventional pages. When enabled, AppSurface reserves /_appsurface/errors/401
, /_appsurface/errors/403
, and /_appsurface/errors/404
for direct rendering, and ignores that path prefix when deciding whether to apply browser-oriented status-page middleware. Static export tooling still consumes only the 404 route and writes only 404.html
; when CDN mode is active, that emitted page is validated and rewritten with the rest of the static graph.
PwaOptions Pwa { get; set; }
Source
Gets or sets Progressive Web App install metadata, diagnostics, and explicit offline behavior.
PWA support is disabled by default. When enabled, AppSurface maps a web app manifest endpoint, optional development diagnostics, and a service-worker endpoint only when an explicit offline strategy is configured. AppSurface does not cache app routes, authenticated pages, POST responses, or user-specific data by default.
HealthOptions Health { get; set; }
Source
Gets or sets platform health and readiness probe endpoint configuration.
Health endpoints are disabled by default. Set HealthOptions.Enabled
to true
when deployment or monitoring infrastructure consumes the public, minimal /health
and /ready
endpoints. Leave the option disabled when the host owns probes directly or does not consume them.
TimeSpan? StartupTimeout { get; set; }
Source
Gets or sets the amount of time AppSurface waits for the web host to complete startup before failing fast.
The default is 10 seconds. Set this to null
only for hosts that intentionally perform long-running startup work before Kestrel binds. The watchdog covers pre-bind stalls caused by package layout, sandboxing, static asset discovery, hosted-service startup, and similar issues; it does not limit normal request processing after the host has started. Timeout diagnostics include safe process context, the observed startup phase, and known Codex sandbox markers when present so operators can rerun outside the sandbox before chasing package or host-layout causes. StartupTimeout
must be null
or greater than TimeSpan.Zero
. Use null
to disable the watchdog instead of TimeSpan.Zero
.
Action<IEndpointRouteBuilder>? MapEndpoints { get; set; }
Source
Gets or sets an optional delegate to configure endpoint routing for the application.
Represents configuration options for Cross-Origin Resource Sharing (CORS) policies.
Use CorsOptions
when an AppSurface web application should register and apply the framework-managed CORS policy. EnableCors
controls whether that policy is active outside development, while EnableAllOriginsInDevelopment
keeps local browser workflows convenient without opening production defaults. Empty AllowedHeaders
or AllowedMethods
collections do not opt into permissive preflight behavior in production; configure the exact browser contract an application supports. Pitfall: enabling CORS in non-development environments still requires at least one allowed origin unless development-only all-origin behavior applies, and the literal wildcard origin *
is rejected outside development for AppSurface-managed CORS. Use explicit origins, wildcard subdomains such as https://*.example.com
, or host-owned ASP.NET Core CORS policy registration for intentionally public wildcard APIs.
bool EnableAllOriginsInDevelopment { get; set; }
Source
Gets or sets a value indicating whether all origins are allowed when running in the development environment. Defaults to true
.
bool EnableCors { get; set; }
Source
Gets or sets a value indicating whether CORS is enabled for the application. Defaults to false
.
string[] AllowedOrigins { get; set; }
Source
Gets or sets the collection of origins permitted to make cross-origin requests. Defaults to an empty array.
Use exact origins such as https://app.example.com
. AppSurface also preserves ASP.NET Core wildcard subdomain support for origins such as https://*.example.com
. The exact literal *
is allowed only for the existing development compatibility path; non-development startup fails before registering the AppSurface-managed CORS policy when this collection contains *
.
string[] AllowedHeaders { get; set; }
Source
Gets or sets the request headers advertised by the CORS policy during browser preflight requests. Defaults to an empty array, which advertises no custom preflight request headers in production.
Configure explicit header names, such as Content-Type
or X-Request-Id
, when preflighted cross-origin callers need them. Use *
only when the application intentionally accepts any request header from allowed origins. Non-preflight CORS responses are still governed by origin policy and browser safelisted request behavior; this collection defines the Access-Control-Allow-Headers
preflight response contract. When EnableAllOriginsInDevelopment
applies, AppSurface still allows any header for local development convenience unless this collection contains one or more configured values.
string[] AllowedMethods { get; set; }
Source
Gets or sets the HTTP methods advertised by the CORS policy during browser preflight requests. Defaults to an empty array, which advertises no preflight-only HTTP methods in production.
Configure explicit method names, such as GET
or POST
, when preflighted cross-origin callers need them. Use *
only when the application intentionally accepts any method from allowed origins. Non-preflight CORS responses are still governed by origin policy and browser method safelisting; this collection defines the Access-Control-Allow-Methods
preflight response contract. When EnableAllOriginsInDevelopment
applies, AppSurface still allows any method for local development convenience unless this collection contains one or more configured values.
string PolicyName { get; set; }
Source
Gets or sets the name of the CORS policy to register. Defaults to "DefaultCorsPolicy"
.
CorsOptions Default { get; }
Source
Gets a default instance of CorsOptions
with default configuration settings.
Maps opt-in AppSurface configuration-audit HTTP diagnostics endpoints.
RouteHandlerBuilder MapAppSurfaceConfigAuditDiagnostics(this IEndpointRouteBuilder endpoints, string authorizationPolicyName)
Maps the AppSurface configuration-audit diagnostics endpoint at the default route.
endpoints
authorizationPolicyName
The route handler builder so hosts can add their own endpoint metadata.
The endpoint is never mapped automatically. Hosts must call this method deliberately, register AppSurface Config services, configure authentication and authorization middleware, and supply an authorization policy that is safe for support-sensitive deployment diagnostics.
RouteHandlerBuilder MapAppSurfaceConfigAuditDiagnostics(this IEndpointRouteBuilder endpoints, string pattern, string authorizationPolicyName)
Maps the AppSurface configuration-audit diagnostics endpoint at a custom route.
endpoints
pattern
authorizationPolicyName
The route handler builder so hosts can add their own endpoint metadata.
The endpoint returns the active host's sanitized ConfigAuditReport
as JSON and sets no-store response headers. It is excluded from API description by default because redacted audit reports can still expose support-sensitive provider names, paths, configuration keys, and deployment structure.
IResult CreateReportResult(HttpContext httpContext, Func<ConfigAuditReport, string> serializeReport)
Creates the diagnostics response for the current request.
httpContext
serializeReport
ConfigAuditReport
.
An IResult
containing either the report JSON or a safe problem response.
This internal overload exists as a test seam for serialization and failure-path verification. Production code should expose the endpoint through MapAppSurfaceConfigAuditDiagnostics(Microsoft.AspNetCore.Routing.IEndpointRouteBuilder, string, string)
instead of calling this helper directly.
Registers the opt-in Web rendering adapter for neutral AppSurface theming.
IServiceCollection AddAppSurfaceWebTheming(this IServiceCollection services)
Registers the Web theme document provider used by the AppSurface theme TagHelpers.
services
The original services
instance.
Call AddAppSurfaceTheming
from the neutral theming package first, then call this method to opt the Web host into the TagHelpers.AppSurfaceThemeRootTagHelper
and TagHelpers.AppSurfaceThemeHeadTagHelper
integration. This method intentionally does not create a default theme pair or silently enable theme rendering.
IServiceCollection AddAppSurfaceWebThemePreferences(this IServiceCollection services, Action<AppSurfaceThemePreferenceOptions>? configure = null)
Registers browser-local System/Light/Dark preference support for the configured Web theme pair.
services
configure
The original services
instance.
ArgumentNullException
services
is null
.ArgumentException
InvalidOperationException
ForgeTrust.AppSurface.Theming.IAppSurfaceThemeResolver
has not been registered before this call. AddAppSurfaceTheming
is one supported registration path; hosts may instead register a compatible custom resolver for the selected pair.
This opt-in establishes the base Web integration and replaces its document provider with a System-first preference document for the same neutral theme pair. It never reads HTTP state, writes a cookie, changes a URL, adds a cache key, or alters the neutral theming package. Existing hosts that use only AddAppSurfaceWebTheming(IServiceCollection)
retain their configured startup mode and emit no preference script.
The browser may persist only explicit light
or dark
values in local storage. Missing, blocked, malformed, and explicit system
values use the operating-system preference through the server-rendered System stylesheet. Calling this method again replaces the previous preference configuration; the latest valid storage key is the one rendered by the head TagHelper.
IServiceCollection AddAppSurfaceWebThemeSelection(this IServiceCollection services)
Registers a scoped host-policy adapter that selects one registered theme pair before Web rendering.
services
The original services
instance.
ArgumentNullException
services
is null
.InvalidOperationException
IAppSurfaceWebThemeSelectionPolicy
, or the built-in ordinary Web document provider are missing; a conflicting adapter is registered; or selection is registered twice.
Register AddAppSurfaceTheming
, a scoped host implementation of IAppSurfaceWebThemeSelectionPolicy
, then this opt-in. The policy consumes only already-authorized application context and returns either one registered AppSurfaceThemeId
or false
for the configured default. Both neutral services must be singletons because the adapter prevalidates and caches package-owned documents once for the application. The adapter validates selected ids and the resolver's configured default identifier and role snapshots against the sealed registry and never serializes a caller-supplied theme pair.
This adapter intentionally cannot compose with browser-local preferences or a consumer-owned IAppSurfaceThemeDocumentProvider
. It caches package-owned documents by immutable pair id, but it never configures HTTP caching, response variation, tenant resolution, authorization, or invalidation. A pair id is not a safe host response-cache key; the host must partition or disable tenant-sensitive response caches.
Specifies the level of MVC feature support to enable in the web application.
The numeric values are explicit because this public enum may be persisted, serialized, or bound by applications. New values should be appended without changing the values documented here.
Controls HTTP status mapping for completed named-canary evaluations.
Describes the current application-owned proof state for a named canary.
Display modes AppSurface can emit into the generated web app manifest.
Values match the standard web app manifest display modes. AppSurface serializes MinimalUi
as minimal-ui
. The numeric values are explicit because this public enum may be persisted, serialized, or bound by applications. New values should be appended without changing the values documented here.
Controls when AppSurface maps browser-facing PWA diagnostics.
Diagnostics can expose deploy and browser-install posture. Keep the default DevelopmentOnly
unless a host intentionally wants the diagnostics available behind its own controls. The numeric values are explicit because this public enum may be persisted, serialized, or bound by applications. New values should be appended without changing the values documented here.
Defines the typed internal settlement states for a snapshot item.
Controls how AppSurface applies its conventional browser-friendly status pages.
Auto
is the default and is the safest choice for most applications because it only enables the conventional pages when MVC view support is already available. Switch to Enabled
when an app must always expose the conventional HTML 401, 403, and 404 experience, even if AppSurface needs to upgrade MVC support to controllers with views during startup. Use Disabled
for API-first applications or when another status-code handling strategy should remain fully in control. The numeric values are explicit because this public enum may be persisted, serialized, or bound by applications. New values should be appended without changing the values documented here.