The Policy Services Portal is an ASP.NET Core 8.0 Razor Pages application on .NET 8, hosted in IIS in-process under the /PolicyPortal base path. Its Startup class derives from the SAIF BolRazorLayoutStartup start-up base class†, so authentication, page chrome, menu and policy context come from the BolMiddleware package† rather than from application source. The application contributes the pages, the page models that derive from the BolMiddleware chain†, a small set of application services, and the Kendo UI front end. It has no database of its own: business data is reached through SAIF API clients and the PolicyCore, Billing and document-rendering APIs behind them.
The application uses a minimal host: Program.cs creates the WebApplication builder and drives a Startup instance by hand rather than calling UseStartup<T>.
#
Call
Effect
Source
1
WebApplication.CreateBuilder(args)
Creates the builder and loads appsettings.json, appsettings.<Environment>.json and environment variables
Program.cs:5
2
new Startup(builder.Configuration)
The constructor sets EnableNewtonsoftJsonSerializer and EnableSessionMiddleware to true; both are switches on BolRazorLayoutStartup†
Program.cs:6, Startup.cs:18
3
startup.ConfigureServices(builder.Services)
Runs the registrations in rows 4 to 9
Program.cs:7
4
base.ConfigureServices(services)
Inherited registrations from BolRazorLayoutStartup†: OIDC authentication, the IBolServicesContainer service set, and the BasicAppMap section bound to IAppMap; called first so the application registrations that follow can replace them
Startup.cs:26
5
services.AddRazorPages(...)
Adds Razor Pages and the AddPageRoute("/Policy/Search", "") convention that serves Policy Search at the site root
Startup.cs:28
6
services.Configure<PortalSettings>(...)
Binds the AppSettings section to PortalSettings
Startup.cs:34
7
services.AddScoped<...>() (four calls)
Registers the application services listed under Composition root
Startup.cs:36
8
services.AddAutoMapper(typeof(Startup))
Registers IMapper and every Profile in the assembly
Startup.Configure registers three calls of its own and then calls the base class last.
#
Middleware
Effect
Source
1
UsePathBase("/PolicyPortal")
Strips the /PolicyPortal base path so every later middleware and the route table see the path without it
Startup.cs:48
2
UseDeveloperExceptionPage() in Development, otherwise UseExceptionHandler("/Error")
Shows the developer exception page locally and the stock /Error page elsewhere
Startup.cs:50
3
UseMiddleware<CorrelationIdMiddleware>()
Reads or creates the X-Correlation-Id value, returns it as a response header and adds it to the log scope
Startup.cs:59
4
base.Configure(app, env)
Inherited pipeline†: session (enabled by the constructor switch), static files, routing, authentication, authorization and Razor Pages endpoints; called last, so rows 1 to 3 run ahead of it
Routes come from the file path under Pages\. The conventions and route templates below change that default. Every URL is relative to the /PolicyPortal base path set at middleware step 1. The application registers no MapControllers or MapGet endpoints, so its AJAX requests are named page handlers, listed on Hosted endpoints. /Error and /AccessDenied have no route template and are served at their file URLs.
BolContextModel, BolMenuModel and BolPolicyModel come from the BolMiddleware package†. They override the page-handler lifecycle hooks, so context resolution, menu and policy header loading, and the redirect to /Policy/Search when a policy page has no policy number in context run before every handler of a derived page†. No application page model overrides those hooks, and the application has no base page model of its own.
Page model
Base
Roles
Serves
SearchModel
BolMenuModel†
PolicyServices.Read, PolicyServices.Underwriting
Policy Search
SummaryModel
BolPolicyModel†
PolicyServices.Read, PolicyServices.Underwriting; refresh balance is PolicyServices.Underwriting only
ConfigureServices calls base.ConfigureServices first†, then adds Razor Pages with its page-route convention, binds PortalSettings, registers the four application services as scoped, and finishes with AutoMapper and the memory cache. The application registers no logging provider of its own. The services supplied by base.ConfigureServices, including IBolServicesContainer†, are not repeated in the table.
Resolves the web context and loads menu and policy header data before the handler runs; redirects to /Policy/Search when a policy page has no policy number
Page route convention
AddPageRoute("/Policy/Search", "")
/Policy/Search
Serves Policy Search at the site root as well as at its file URL
SummaryModel.OnPostRefreshBalanceAsync and NewModel
Only underwriting staff can refresh a balance or start an endorsement; others are redirected to /AccessDenied
Anti-forgery
Razor Pages default for unsafe verbs
every POST handler
Validates the request verification token. No page model declares [IgnoreAntiforgeryToken] and Startup registers no override, so every POST handler, including OnPostRefreshBalanceAsync and OnPostReadAsync, is validated
Tag helper set
Kendo.Mvc
application
Makes the Kendo UI tag helpers, such as kendo-grid and kendo-dropdownlist, available on every page
Inherited context: policy context, menu and header are resolved by the BolMiddleware page-model chain† and are cited from each screen as inherited behavior, not rewritten per page.
Handlers as the endpoint layer: AJAX, grid and file requests are named page handlers on the page that uses them; there are no API controllers.
Thin page models: handlers delegate to the application services above and map results to view models with AutoMapper.
Server-rendered partials: dialog content is a partial view fetched on demand and injected into a container, not built in script.
[!NOTE]
Statements marked with * are inferred from code patterns. Statements marked with ** could not be verified from available source. Statements marked with † are sourced from package documentation retrieved with the Legends CLI.