---
title: SAIF.Presentation.Web.MVC business rules
summary: Enumerated business rules with per-rule trigger, enforcement, and outcomes.
status: draft
owner: SAIF Documentation Team
last_reviewed: 2026-08-17
library: SAIF.Presentation.Web.MVC
reference_type: package
---

# SAIF.Presentation.Web.MVC business rules

This page captures business rules enforced by this library.

## BR-MVC-001: Session timeout redirect

| Field | Value |
| --- | --- |
| **Statement** | If a postback occurs against a brand-new session (`IsPostBack And Session.IsNewSession`), the request must be redirected rather than processed further. |
| **Trigger** | A postback request arrives while `HttpContext.Session.IsNewSession` is true (the original session has expired). |
| **Enforcement** | `clsControllerBase.Initialize()` — redirects to the application root with a timeout message for internal clients (per the local `IsInsideClient` classification, [BR-MVC-008](#br-mvc-008-internal-address-classification)), or to `/OnlineLogin/LoginScreen.aspx` (clearing the `SAIFAUTH` cookie) otherwise. |
| **Outcome** | The user is redirected before any model retrieval or page processing occurs; a `ThreadAbortException` from the redirect is swallowed via `Thread.ResetAbort()`. |
| **Source** | SAIF.Presentation.Web.MVC\clsControllerBase.vb |

---

## BR-MVC-002: Menu-based page authorization

| Field | Value |
| --- | --- |
| **Statement** | A request is denied unless `NavigationContext.IsMenuItem(currentApp, currentItem)` returns `True` for the current application/page path. |
| **Trigger** | Every request processed by `clsControllerBase.Initialize()`, after `NavigationContext` has been constructed/reused for the current user. |
| **Enforcement** | `clsControllerBase.RedirectUnauthorizedUsers()` — on denial, clears `Session("navdata")` and redirects to `/OnlineLogin/LoginScreen.aspx`, logging a warning trace. |
| **Outcome** | Page-level authorization is entirely data-driven: access is granted only if the user's per-user, database-provisioned `clsMenuAuthorizedItemCollection` (from `SAIF.Business.Menu`) contains a matching entry. |
| **Source** | SAIF.Presentation.Web.MVC\clsControllerBase.vb; SAIF.Presentation.Web.MVC\NavigationContext.vb |

---

## BR-MVC-003: Authenticated principal required

| Field | Value |
| --- | --- |
| **Statement** | A request must resolve an authenticated `clsSecurityPrincipal`, or originate from an address recognized as internal by the external `clsEnvironment.InternalAddress` check (in which case an NTLM/Basic challenge (HTTP 401) is issued), or else an `Exception("Not Authorized.")` is thrown. |
| **Trigger** | Every request processed by `clsControllerBase.Initialize()`, when `Model.Context.SecurityPrincipal` is not already populated. |
| **Enforcement** | `clsControllerBase.SecurityCheck()` — constructs a new `clsSecurityPrincipal(Platform.Web)` and checks `.IsAuthenticated`; if not authenticated and `clsEnvironment.InternalAddress(Request.UserHostAddress)` (an external dependency from `SAIF.BOF.Framework`, distinct from the local `IsInsideClient` property behind [BR-MVC-008](#br-mvc-008-internal-address-classification)) returns `True`, issues a 401 challenge and ends the response; otherwise throws `Exception("Not Authorized.")`. |
| **Outcome** | Establishes *who* the caller is (identity presence), not *what* they may access — page-level entitlement is handled separately by [BR-MVC-002](#br-mvc-002-menu-based-page-authorization). |
| **Source** | SAIF.Presentation.Web.MVC\clsControllerBase.vb |

---

## BR-MVC-004: Multi-model requires configuration

| Field | Value |
| --- | --- |
| **Statement** | `Navigate2` (new-model navigation) may only be called when the controller was constructed with `SupportsMultiModel = True`. |
| **Trigger** | A consuming controller calls `Navigate2(inTargetApplication, inTargetView)` (new-model navigation overload). |
| **Enforcement** | `clsControllerBase.Navigate2` — throws `ApplicationException("Navigate2 only supported with Multiple Model configuration.")` if `SupportsMultiModel` is `False`. |
| **Outcome** | Prevents creation of a second concurrent model/view-data session entry for controllers not configured to support multiple concurrent model instances. |
| **Source** | SAIF.Presentation.Web.MVC\clsControllerBase.vb |

---

## BR-MVC-005: Cross-application context transfer only across distinct applications

| Field | Value |
| --- | --- |
| **Statement** | Context values are only retrieved from the shared `Context` table when the referring application name differs (case-insensitively) from the current application name; same-application navigation instead reuses the in-session `ViewID`. |
| **Trigger** | `clsControllerBase.CheckContext(inAppPath)` (on a referrer being present) and `clsControllerBase.Navigate(inTargetApplication, inTargetView)` (on outbound navigation). |
| **Enforcement** | `clsControllerBase.CheckContext` compares `SourceAppName`/`CurrentAppName` before calling `Model.Context.RetrieveContext`; `Navigate` compares `SourceApp`/`TargetApp` before calling `Model.Context.SaveContext`. |
| **Outcome** | Cross-application hand-off values are only persisted to or read from SQL Server when actually crossing an IIS application boundary, avoiding unnecessary database round-trips for in-application navigation. |
| **Tables** | [Context](database-tables.md#context) |
| **SQL** | [SQL-MVC-002](sql/SQL-MVC-002-retrieve-cross-application-context.md), [SQL-MVC-001](sql/SQL-MVC-001-insert-context-value.md) |
| **Source** | SAIF.Presentation.Web.MVC\clsControllerBase.vb |

---

## BR-MVC-006: Write requires prior validation

| Field | Value |
| --- | --- |
| **Statement** | `WriteData()` is only invoked if `ValidateData()` returns `True`. |
| **Trigger** | A consuming controller calls `clsModelBase.Write()` (typically on a save postback). |
| **Enforcement** | `clsModelBase.Write()` — calls the abstract `ValidateData()`; only on a `True` result does it call the abstract `WriteData()`. Both are implemented by the concrete model in the consuming application. |
| **Outcome** | Guarantees no persistence occurs against unvalidated model state, though the concrete validation/write logic itself lives entirely outside this library. |
| **Source** | SAIF.Presentation.Web.MVC\clsModelBase.vb |

---

## BR-MVC-007: Session-based ViewState for external/flagged users

| Field | Value |
| --- | --- |
| **Statement** | ViewState is persisted server-side in `Session` (rather than in the page) when `ViewStateInSession = ALL_USERS`, or when `ViewStateInSession = EXTERNAL_USERS` (or the `EXT_VIEWSTATE_SESSION` app setting is true) **and** the requesting host address does not match the internal `10.*` pattern. |
| **Trigger** | Every page request through `ViewPageBase.PageStatePersister`. |
| **Enforcement** | `ViewPageBase.PageStatePersister` property getter — branches on the `VIEWSTATE_CTRL_ENUM` value and the `EXT_VIEWSTATE_SESSION` AppSettings flag. |
| **Outcome** | Reduces ViewState payload size for external/flagged users at the cost of server-side session memory. |
| **Source** | SAIF.Presentation.Web.MVC\ViewPageBase.aspx.vb |

---

## BR-MVC-008: Internal-address classification

| Field | Value |
| --- | --- |
| **Statement** | A request is treated as originating "inside the client network" if the caller's host address matches `10.*`, `131.131.*.*`, or `127.0.0.1`. |
| **Trigger** | Evaluated on every request via `clsControllerBase.IsInsideClient`. |
| **Enforcement** | `clsControllerBase.IsInsideClient` (`Like` pattern match against `Request.UserHostAddress`); this classification feeds the session-timeout redirect target ([BR-MVC-001](#br-mvc-001-session-timeout-redirect)) and the server-side ViewState-in-session behavior ([BR-MVC-007](#br-mvc-007-session-based-viewstate-for-externalflagged-users)). It is a separate, local classification from the `clsEnvironment.InternalAddress` external dependency that gates the unauthenticated HTTP 401 challenge in [BR-MVC-003](#br-mvc-003-authenticated-principal-required). |
| **Outcome** | Internal callers (timed-out session, postback) receive an in-application redirect with a timeout message; external callers instead are redirected to the online login page with the `SAIFAUTH` cookie cleared. This hardcodes SAIF's internal network topology directly into the library. |
| **Source** | SAIF.Presentation.Web.MVC\clsControllerBase.vb |

## Notes
- No inherited business rules were identified — `clsSecurityPrincipal`, `clsEnvironment`, `clsLogError`, and `clsConnection` are consumed as opaque external framework types (from `SAIF.BOF.Framework`, not part of this run's documented library set), and no rule-bearing base-class behavior from those types could be confirmed from this library's source alone.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Security and authorization](security-authorization.md)
- [Configuration](configuration.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [API reference](api/index.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources
- SAIF.Presentation.Web.MVC\clsContext.vb
- SAIF.Presentation.Web.MVC\clsControllerBase.vb
- SAIF.Presentation.Web.MVC\clsModelBase.vb
- SAIF.Presentation.Web.MVC\ViewPageBase.aspx.vb
- SAIF.Presentation.Web.MVC\NavigationContext.vb
