BolMiddleware architecture¶
BolMiddleware is a net8.0 ASP.NET Core Razor class library shipped as a NuGet package. It gives consumer Razor Pages applications the Business Online (BOL) page chrome: shared layouts, menu and policy header view components, a chain of abstract PageModel base classes, and thin service facades over remote BOL, Policy, and SAIF platform API clients. Consumers adopt it by inheriting BolRazorLayoutStartup and deriving their pages from BolContextModel, BolMenuModel, or BolPolicyModel. The library has no host entry point and no database access; all persistence is delegated to remote APIs reached through internal client packages.
Responsibilities¶
- Provide a startup base class (
BolRazorLayoutStartup) that extendsOidcRazorStartup, enables the legacy BOL authentication middleware, registers BOL services, and binds theBasicAppMapoptions. - Register BOL services and the four API client packages through
RegisterBolServices. - Resolve and persist the BOL web context for every request through
BolContextModel, using a short-lived cookie, the ASP.NET Core session, and the remote BOL Context API. - Load the BOL menu for the current user and drive cross-application navigation through
BolMenuModel. - Load the policy header, validate access to the policy, and expose the policy association dropdown through
BolPolicyModel. - Ship four Razor layouts, three view components, shared partials, a menu navigation script, and compiled styles as static web assets.
- Offer optional consumer customization hooks as partial views under
MiddlewareIncludes/.
Component boundaries¶
- Host integration (
BolRazorLayoutStartup,BolServiceExtensions): owns service registration and options binding; the middleware pipeline is inherited fromOidcRazorStartupand is not defined here. - Page pipeline (
BolContextModel,BolMenuModel,BolPolicyModel): abstract PageModels that form an inheritance chain and hook the Razor Pages handler filter events. - Service layer (
BolServicesContainer,SecurityService,WebContextService,MenuService,PolicyHeaderService,CookieService,ContextCookieHelperService,RequestHelper): facades over the remote API clients and HTTP helpers; they catch exceptions and fall back to defaults. - Presentation (RCL views and view components):
_PolicyLayout,_PolicyOnlyLayout,_ContextOnlyLayout,_MenuOnlyLayout, and theBolPolicyHeader,BolSideMenu, andBolTopMenuview components render data supplied by the PageModel. - Client script (
wwwroot/js/MenuNavigation.js): intercepts menu link clicks and context box key presses and posts the context form for cross-application navigation. - Remote dependencies (outside this library): BOL Context API, BOL Menu API, Policy Header API, Policy Core API, the SAIF security client, and the SAIF environment client. Their endpoints and transport are package internals and unknown** from this repository.
Interaction model¶
- A consumer page derives from a BolMiddleware PageModel. On handler selection the model reads the
BolContextcookie and theApplicationNamesetting. - On handler execution the model resolves the web context in priority order: cookie, referring application lookup, context id (
cidquery orWebContextIdform value), then session. - State is held in three layers: the
BolContextHttpOnly cookie (10 second lifetime), ASP.NET Core session JSON for the context, menu, and policy header, and the remote BOL Context API for cross-application persistence. BolMenuModelloads the menu throughIMenuService, andBolPolicyModelloads the policy header throughIPolicyHeaderServiceand validates the policy throughSecurityService, which callsIPolicyCoreApiClient.IsValidPolicyForUser. External user information comes from a different client:BolContextModelcallsSecurityService.GetCurrentExternalUserAsyncfromOnPageHandlerExecuting, which callsISecurityClient.GetExternalUser.- Layouts render the BOL chrome by invoking the view components with data from the PageModel.
- Cross-application navigation hands the context off through a
cidvalue or a referring application lookup. - Two sync-over-async calls exist in the page pipeline: the external user lookup in
BolContextModeland the policy validation inBolPolicyModel.
Architecture diagram¶
The following diagram shows high-level component interactions.
flowchart TD
Consumer[Consumer Razor Pages app] --> Startup[BolRazorLayoutStartup]
Consumer --> Models[BolContextModel to BolMenuModel to BolPolicyModel]
Startup --> Reg[RegisterBolServices]
Models --> Container[BolServicesContainer]
Models --> Facades[Context Menu PolicyHeader Security services]
Models --> Cookie[Cookie and session state]
Facades --> Clients[Internal API client packages]
Clients --> Remote[BOL and Policy APIs]
Models --> Layouts[Layouts and view components]
Layouts --> Script[MenuNavigation.js]
Sequence diagram¶
The following diagram shows the primary request/response sequence.
sequenceDiagram
participant Browser
participant Page as Consumer page model
participant Ctx as WebContextService
participant Menu as MenuService
participant Hdr as PolicyHeaderService
Browser->>Page: GET page with cid or cookie
Page->>Page: Read BolContext cookie and session
Page->>Ctx: GetContext by context id or session
Ctx-->>Page: Context result
Page->>Menu: GetMenu for current user
Menu-->>Page: Menu data
Page->>Hdr: GetHeader for policy
Hdr-->>Page: Policy header
Page-->>Browser: Razor page with BOL layout
Design constraints¶
- The library targets net8.0 only and requires the
Microsoft.AspNetCore.Appshared framework. - The startup pipeline order is inherited from
OidcRazorStartupand is unknown** from this repository. ISecurityClient,IEnvironmentClient, andISaifLogServiceare resolved but not registered here; they are expected from the base startup*.AddSession()is called, butUseSession()and a distributed cache are not configured in this library; whether the base startup enables session middleware is unknown**.IBolContextApiClientis registered twice; the last registration wins for single resolution.IAppMapresolves a defaultBasicAppMapinstance, while views read the configuredIOptions<BasicAppMap>directly.- Singleton facades depend on API clients whose lifetimes are set inside the packages, so a lifetime capture risk is unknown**.
- View component
InvokeAsyncmethods are declared async but contain noawait.
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with**could not be confirmed; treat as unknown until verified.
Related documentation¶
- Index
- Overview
- Dependencies
- Configuration
- Operations and processes
- Business rules
- Security and authorization
- Service registration
- API reference
Sources¶
- src/BolMiddleware/BolMiddleware.csproj
- src/BolMiddleware/BolRazorLayoutStartup.cs
- src/BolMiddleware/Extensions/BolMiddlewareExtensions.cs
- src/BolMiddleware/Models/BolContextModel.cs
- src/BolMiddleware/Models/BolMenuModel.cs
- src/BolMiddleware/Models/BolPolicyModel.cs
- src/BolMiddleware/Services/BolServicesContainer.cs
- src/BolMiddleware/Services/Context/WebContextService.cs
- src/BolMiddleware/Services/Menu/MenuService.cs
- src/BolMiddleware/Services/Headers/Policy/PolicyHeaderService.cs
- src/BolMiddleware/Services/Security/SecurityService.cs
- src/BolMiddleware/ViewComponents/BolPolicyHeaderViewComponent.cs
- src/BolMiddleware/Pages/Shared/_PolicyLayout.cshtml
- src/BolMiddleware/wwwroot/js/MenuNavigation.js