---
title: SAIF.Presentation.Web.Controls.V2.Menu architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-17
library: SAIF.Presentation.Web.Controls.V2.Menu
reference_type: package
---

# SAIF.Presentation.Web.Controls.V2.Menu architecture

`SAIF.Presentation.Web.Controls.V2.Menu` renders the Business Online navigation menu and page toolbar through three server controls: `SAIFMenu` (left-hand favourites/applications accordion with a context search box), `SAIFMenuTop` (top page-link row plus action toolbar), and `SAIFImageButton` (the styled image button used by both). All menu content is derived from the signed-in user's authorised menu items (via `NavigationContext`), and user layout choices are persisted through `clsPreferences`.

## Responsibilities
- Render the left-hand navigation menu (`SAIFMenu`): context search box, favourites list, and a collapsible applications accordion trimmed to the current user's authorised categories/items.
- Render the top navigation row and action toolbar (`SAIFMenuTop`): page links plus toolbar buttons (`Insert`, `Save`, `Delete`, `Print`, `Download`, `PrefsSet`/`PrefsClear`, `Help`, `Edit`, `Cancel`, `Calculate`, `Preview`, `Email`, `Submit`) gated by per-page capability flags.
- Persist and read the user's "show applications pane" preference (`SHOWAPPS`, application `BOMENU`) through `SAIF.Presentation.clsPreferences`.
- Raise navigation and toolbar-action events (`MenuNavigate`, `ToolbarClick`, `DefaultOnSubmit`) for the hosting page to act on; the controls never navigate or perform actions themselves (except the "Change Password" redirect for external clients, see [BR-MENU-044](business-rules.md#br-menu-044)).

## Component boundaries
- **`SAIFMenu`**: owns the context box, favourites list, and applications accordion; obtains its authorization data and preference store independently of `SAIFMenuTop`.
- **`SAIFMenuTop`**: owns the top link row and the toolbar button model (`clsMenuButton`, `ToolBarButton` enum); duplicates `SAIFMenu`'s `GetNavigationData` logic verbatim rather than sharing it.
- **`SAIFImageButton`**: a shared low-level image-button control consumed by both `SAIFMenu` and `SAIFMenuTop` for toolbar/menu icon rendering with AJAX activity-indicator behavior.

No type in this library inherits from a `SAIF.Framework.*` or `SAIF.BOF.Framework` base class; `SAIFMenu` inherits `System.Web.UI.Control`, `SAIFMenuTop` inherits `WebControl`, and `SAIFImageButton` inherits `ImageButton`. Framework/sibling-library coupling is entirely by composition (held references and static member calls), not inheritance.

## Interaction model
- Both `SAIFMenu` and `SAIFMenuTop` cast the hosting page to `SAIF.Presentation.Web.MVC.ViewPageBase`, subscribe to its `PreLoad` event, and use its `ViewID` to namespace session/ViewState entries ([BR-MENU-005](business-rules.md#br-menu-005), [BR-MENU-036](business-rules.md#br-menu-036)).
- `GetNavigationData()` (duplicated in both controls) returns the `NavigationContext` cached in `Session("navdata")`, constructing it on first use from the Windows logon identity (`Request.LogonUserIdentity.Name`, domain-stripped and upper-cased) via `SAIF.Presentation.Web.MVC.NavigationContext` ([BR-MENU-002](business-rules.md#br-menu-002), [BR-MENU-003](business-rules.md#br-menu-003), [BR-MENU-004](business-rules.md#br-menu-004)). Every subsequent render reuses the session-cached authorization set — no further database access occurs within a session.
- `SAIFMenu.AddLinks`/`AddFavorites` and `SAIFMenuTop.BuildLinkCollection` trim the rendered menu to only the items present in `NavigationContext.MenuAuthorizedItems` and flagged `IsVisible` ([BR-MENU-029](business-rules.md#br-menu-029)).
- `SAIFMenuTop.Page_PreLoad` gates each toolbar button's visibility/enabled state on the current authorized page's `IsDisplayInsert`/`IsDisplaySave`/`IsDisplayDelete`/`IsDisplayPrint`/ `IsDisplayDownload`/`IsDisplaySavePreferences`/`IsDisplayHelp` flags ([BR-MENU-059](business-rules.md#br-menu-059)).
- `SAIFMenu.Preferences` constructs `New clsPreferences(userID, "BOMENU")` (only when the identity name splits into exactly two `DOMAIN\user` parts) to read/write the `SHOWAPPS` preference that controls whether the applications pane starts expanded or collapsed ([BR-MENU-041](business-rules.md#br-menu-041)–[BR-MENU-043](business-rules.md#br-menu-043)).
- Clicking a menu item resolves the target through `NavigationData.MenuAuthorizedItems.Item(ItemSeq)` before raising `MenuNavigate`, so the navigation target always comes from the authorized set rather than posted data ([BR-MENU-046](business-rules.md#br-menu-046)).

## Architecture diagram
The following diagram shows the rendering and data flow for both menu controls.

```mermaid
graph TD
  A[Windows logon identity] --> B["NavigationContext (SAIF.Presentation.Web.MVC)"]
  B --> C["clsMenuAuthorizedItemCollection (SAIF.Business.Menu)"]
  B --> D["Session('navdata') cache"]
  C --> E[SAIFMenu favourites + applications accordion]
  C --> F[SAIFMenuTop page links + toolbar buttons]
  E --> G["MenuNavigate event to host page"]
  F --> G
  F --> H["ToolbarClick event to host page"]
  I["clsPreferences (SAIF.Presentation)"] --> E
  E --> I
  J[SAIFImageButton] --> F
```

## Sequence diagram
The following diagram shows the per-session navigation-context bootstrap and menu render sequence.

```mermaid
sequenceDiagram
	participant Page
	participant Menu as SAIFMenu / SAIFMenuTop
	participant Nav as NavigationContext
	participant Session
	Page->>Menu: PreLoad / Load
	Menu->>Session: Session("navdata")?
	alt cached
		Session-->>Menu: NavigationContext
	else not cached
		Menu->>Nav: New(userid from LogonUserIdentity)
		Nav-->>Menu: MenuAuthorizedItems
		Menu->>Session: Cache NavigationContext
	end
	Menu->>Menu: Trim menu/toolbar to authorized, visible items
	Menu-->>Page: Rendered menu/toolbar, MenuNavigate / ToolbarClick events
```

## Design constraints
- The authorization set is cached in `Session("navdata")` for the life of the session, so menu security/preference changes take effect only after the session is recycled.*
- `GetNavigationData` is duplicated verbatim across `SAIFMenu` and `SAIFMenuTop` rather than shared, a maintenance risk for the two controls drifting out of sync.
- Toolbar buttons are hidden/disabled based on capability flags, but click handlers do not re-check those flags — a forged postback targeting a disabled action is not demonstrably blocked at this layer ([BR-MENU-077](business-rules.md#br-menu-077)); the hosting page must re-validate.*
- `SAIFMenu`/`SAIFMenuTop.RenderControl` write exception message, source, and stack trace into the rendered page on error ([BR-MENU-071](business-rules.md#br-menu-071)) — an information-disclosure risk in production.
- The controls require a fixed `/Resources/MenuImages/*` and `/Resources/Scripts/Controls/ImageButton.js` asset layout, plus specific CSS classes, in every hosting application.
- A duplicate `NavigationContext` type exists in both `SAIF.Presentation.Web.MVC` and `SAIF.Presentation.Web.Core.Infragistics111`; because this project references only the MVC project, the MVC copy is the one bound here.*

> **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)
- [Database tables](database-tables.md)
- [Security and authorization](security-authorization.md)
- [Control catalog](control-catalog.md)
- [API reference](api/index.md)

## Sources
- `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenu.vb`
- `SAIF.Presentation.Web.Controls.V2.Menu/SAIFMenuTop.vb`
- `SAIF.Presentation.Web.Controls.V2.Menu/SAIFImageButton.vb`
- `SAIF.Presentation.Web.MVC/NavigationContext.vb`
