---
title: SAIF.Presentation.Web.MVC architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: SAIF Documentation Team
last_reviewed: 2026-08-17
library: SAIF.Presentation.Web.MVC
reference_type: package
---

# SAIF.Presentation.Web.MVC architecture

`SAIF.Presentation.Web.MVC` supplies the shared base-class framework for a "poor-man's MVC" pattern layered on classic ASP.NET WebForms, used across SAIF's legacy front-end applications. It does not implement ASP.NET MVC (no routing, no `Controller`/`ActionResult` types); instead it retrofits Model/View/Controller/Factory roles onto WebForms `Page`/`UserControl` classes and adds cross-application session/context hand-off, menu-driven authorization, and centralized error handling.

## Responsibilities
- Orchestrate the WebForms page/control request lifecycle (`clsControllerBase.Initialize`/`CallRetrieve`/`UnInitialize`) on behalf of concrete controllers supplied by each consuming application.
- Enforce two authorization gates on every request: authenticated-principal presence (`SecurityCheck`) and menu-driven page authorization (`RedirectUnauthorizedUsers` via `NavigationContext`) — see [Security and authorization](security-authorization.md).
- Persist and retrieve cross-application "context" hand-off values (claim ID, policy number, SAIF claim number, provider location sequence number) in a SQL Server `Context` table so a user's in-flight state survives navigation between separate SAIF web applications — see [Database tables](database-tables.md) and [SQL catalog](sql/index.md).
- Provide an abstract `clsModelBase`/`clsFactoryBase` contract that consuming applications implement to supply concrete models, controllers, and validation/write behavior.
- Centralize unhandled-exception routing (`ViewPageBase.ProcessError`/`clsControllerBase.HandleErrors`), including SAIF-exception-type dispatch, logging, and redirect to a configurable error page.
- Resolve environment- and deployment-specific settings (SQL Server/Oracle connection keys, trace toggles, error-page overrides, ViewState-in-session behavior) through the Environment API and `Web.config` `<appSettings>` — see [Configuration](configuration.md).

## Component boundaries
- `ViewPageBase` / `ViewControlBase` — **View** layer: WebForms `Page`/`UserControl` code-behind base classes; own the ASP.NET page lifecycle events (`Page_Init`, `Page_Load`, `Page_PreRender`, `Page_Unload`, `Page_Error`) and delegate all non-rendering behavior to a `clsControllerBase` instance obtained from a `clsFactoryBase`. `ViewPageBase` also owns ViewState-in-session persistence (`PageStatePersister`) and Infragistics-control-aware client focus scripting (`NavigationManager` nested class, reflection-only coupling — no compile-time `Infragistics.*` reference).
- `clsControllerBase` — **Controller** layer: orchestrates security checks, `NavigationContext` construction/caching in `Session("navdata")`, cross-application context hand-off (`CheckContext`/`Navigate`/`Navigate2`), and error handling. It is the central coordination boundary between the View and Model layers.
- `clsModelBase` — **Model** layer (abstract): holds a `clsContext` and `clsPreferences` reference, defines the `ValidateData`/`WriteData` contract invoked by the `Write()` template method, and exposes shared input-validation helpers. Concrete models are implemented entirely by consuming applications; this library defines only the contract.
- `clsFactoryBase` — **Factory** abstraction (abstract): lets each consuming application supply its own concrete `Controller`/`Model` pair via `GetController()`/`GetModel()`, decoupling `ViewPageBase`/`ViewControlBase` from any specific application's concrete types.
- `clsContext` / `clsOnlineContext` — cross-request/cross-application **state-transfer** boundary: a plain (non-BOF-criteria) class whose private nested `clsContextRepository`/`clsSQL` perform direct ADO.NET SQL Server access against the `Context` table. `clsOnlineContext` is a thin subclass fixing `ApplicationName = "Online"`.
- `NavigationContext` — **menu-authorization lookup** boundary: wraps `SAIF.Business.Menu` collections (`clsMenuAuthorizedItemCollection`, `clsApplicationCodeCollection`, `clsMenuCategoryCodeCollection`), sourced through an Oracle data layer (`clsMSOracleDataLayer`) constructed in this library, to answer "is this page authorized for this user" queries.

## Interaction model
- A request enters through `ViewPageBase.Page_Init`, which asks the concrete `clsFactoryBase.GetController()` for a controller instance and calls `clsControllerBase.Initialize()`.
- `Initialize()` performs, in order: session-timeout redirect check, `SecurityCheck()` (principal presence/NTLM challenge), lazy construction/reuse of `NavigationContext` in `Session("navdata")`, `RedirectUnauthorizedUsers()` (menu-based page gate), `Model.Pre_Init()`, the overridable `Load()` hook, query-string processing, and — if a referrer is present — `CheckContext()` for cross-application state hand-off.
- `ViewPageBase.Page_Load` calls `clsControllerBase.CallRetrieve()`, which reflects over page controls and invokes the concrete controller's abstract `Retrieve(controls, targetView)` hook.
- `ViewPageBase.Page_PreRender` triggers client-focus script generation (`NavigationManager.GenerateScripts`) and optional trace output.
- `ViewPageBase.Page_Unload` calls `clsControllerBase.UnInitialize()`, persisting `Model` and `ViewData` into `Session`.
- `ViewPageBase.Page_Error` calls `ProcessError()`, which dispatches on SAIF-exception type (via reflection on the runtime type name `clsSAIFException`) or falls through to `clsControllerBase.HandleErrors()` for logging, emailing, and redirect to a central error page.
- Cross-application navigation (`Navigate`/`Navigate2`) persists context values to the shared SQL Server `Context` table (delete-then-insert) when navigating to a different application, or reuses the in-session `ViewID` when navigating within the same application (see [BR-MVC-005](business-rules.md#br-mvc-005-cross-application-context-transfer-only-across-distinct-applications)).
- The `Write()` template method on `clsModelBase` only invokes the concrete `WriteData()` if the concrete `ValidateData()` returns `True` (see [BR-MVC-006](business-rules.md#br-mvc-006-write-requires-prior-validation)).

## Architecture diagram
The following diagram shows the layered component structure and where it crosses out to external databases and the consuming application's concrete types.

```mermaid
flowchart TD
	View["ViewPageBase / ViewControlBase<br>(View layer)"] --> Factory["clsFactoryBase<br>(Factory, abstract)"]
	Factory --> Controller["clsControllerBase<br>(Controller layer)"]
	Controller --> Model["clsModelBase<br>(Model layer, abstract)"]
	Controller --> Nav["NavigationContext<br>(menu authorization)"]
	Controller --> Ctx["clsContext / clsOnlineContext<br>(cross-app state transfer)"]
	Model --> Prefs["clsPreferences<br>SAIF.Presentation"]
	Nav --> MenuLib["SAIF.Business.Menu<br>clsMenuAuthorizedItemCollection etc."]
	Nav --> OracleLayer["clsMSOracleDataLayer<br>SAIF.Framework.Common"]
	OracleLayer --> OracleDB[("Oracle DB<br>menu/authorization data")]
	Ctx --> SqlServerDB[("SQL Server<br>Context table<br>catalog NETFRAMEWORK")]
	Controller --> ErrorLog["clsLogError / clsLogTrace<br>SAIF.BOF.Framework"]
```

## Sequence diagram
The following diagram shows the request lifecycle through the base classes, including the authorization gates and the cross-application context store.

```mermaid
sequenceDiagram
    participant Browser
    participant ViewPageBase
    participant clsControllerBase
    participant clsFactoryBase
    participant ConcreteModel as clsModelBase (concrete)
    participant NavigationContext
    participant Context as clsContext (Context table)

    Browser->>ViewPageBase: HTTP request
    ViewPageBase->>clsFactoryBase: GetController()
    clsFactoryBase-->>ViewPageBase: clsControllerBase instance
    ViewPageBase->>clsControllerBase: Initialize()
    clsControllerBase->>clsControllerBase: SecurityCheck()
    clsControllerBase->>NavigationContext: new NavigationContext(UserID)
    clsControllerBase->>NavigationContext: IsMenuItem(app, page)
    NavigationContext-->>clsControllerBase: authorized true/false
    clsControllerBase->>ConcreteModel: Pre_Init()
    clsControllerBase->>Context: CheckContext() / RetrieveContext()
    ViewPageBase->>clsControllerBase: CallRetrieve()
    clsControllerBase->>ConcreteModel: Retrieve(controls, targetView)
    ViewPageBase->>clsControllerBase: UnInitialize()
    clsControllerBase->>Browser: Session(Model, ViewData) persisted
```

## Design constraints
- No ASP.NET MVC routing or `Controller`/`ActionResult` types are used; the "MVC" naming is a role-based retrofit onto WebForms, and concrete `Retrieve`, `HandleContext`, `HandleQuerystring`, `ValidateData`, and `WriteData` behavior lives entirely in downstream consuming applications, not in this library.**
- Authorization is coarse-grained and local/programmatic — no `[SAIFAuthorize]` attributes, no WCF `SecurityService` client, and no direct AD group checks exist in this library; page-level access is gated by database-provisioned menu entries (`SAIF.Business.Menu`) rather than named AD resources. See [Security and authorization](security-authorization.md).
- Cross-application state hand-off depends on a directly-owned SQL Server dependency: `clsContext`'s private `clsContextRepository` opens raw `SqlConnection`/`SqlCommand` objects against a `Context` table in the `NETFRAMEWORK` catalog, resolved via `EnvironmentConfigKeys.NetFrameworkSqlServer` — this is not the standard BOF `IBusinessCriteria` pattern used elsewhere in SAIF. See [Database tables](database-tables.md) and [SQL catalog](sql/index.md).
- `NavigationContext` introduces an indirect Oracle dependency (`EnvironmentConfigKeys.OracleDatabase` via `clsMSOracleDataLayer`) for menu/authorization data, meaning this library's request pipeline depends on the availability of two separate database engines (SQL Server for context hand-off, Oracle for menu authorization) on every authorized request.
- Session-timeout and internal-address classification hard-codes network literals (`10.*`, `131.131.*.*`, `127.0.0.1`) directly in `clsControllerBase`'s local `IsInsideClient` property, coupling the session-timeout/ViewState-persistence behavior to the SAIF internal network topology (see [BR-MVC-008](business-rules.md#br-mvc-008-internal-address-classification)). The unauthenticated HTTP 401 vs. deny outcome in `SecurityCheck()` is instead gated by the separate external `clsEnvironment.InternalAddress` dependency (see [Security and authorization](security-authorization.md)).
- All environment-varying configuration is resolved through the plain-text `GetConfigSetting` Environment API — no `GetSecureConfigSetting`/`SystemHashUtil.ComputeHash` calls exist in this library, so the SQL Server and Oracle connection keys it resolves are not treated as secure settings. See [Configuration](configuration.md).
- The `.aspx`/`.ascx` markup files declare `Inherits="SAIF.ViewPageBase"`/`Inherits="SAIF.ViewControlBase"` (namespace `SAIF`), inconsistent with the project's actual root namespace (`SAIF.Presentation.Web.MVC`); this suggests the markup is legacy scaffolding not served directly, with real markup living in each consuming application.**
- Per the root `.nuspec`, this library contributes source (`.vb` files), not a compiled binary, to the `SAIF.BOF.Presentation.Web.Infragistics103` NuGet package; the compiled binary shipped in that package is built from `SAIF.Presentation.Web.Core.Infragistics103`.*

> **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](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)


## Sources
- SAIF.Presentation.Web.MVC\clsContext.vb
- SAIF.Presentation.Web.MVC\clsOnlineContext.vb
- SAIF.Presentation.Web.MVC\clsControllerBase.vb
- SAIF.Presentation.Web.MVC\clsFactoryBase.vb
- SAIF.Presentation.Web.MVC\clsModelBase.vb
- SAIF.Presentation.Web.MVC\NavigationContext.vb
- SAIF.Presentation.Web.MVC\ViewControlBase.ascx.vb
- SAIF.Presentation.Web.MVC\ViewPageBase.aspx.vb
- SAIF.Presentation.Web.MVC\SAIF.Presentation.Web.MVC.vbproj
- SAIF.BOF.Presentation.Web.Infragistics103.nuspec
