---
title: SAIF.Presentation.Web.Controls.V2.Menu architecture
summary: Architectural responsibilities, boundaries, and interaction patterns for the ASP.NET WebForms navigation control library (side menu, top toolbar, and shared image-button control).
status: draft
owner: SAIF documentation team
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` is a pure ASP.NET WebForms presentation-tier control library that renders application navigation chrome — a collapsible left-side "Applications"/Favorites panel (`SAIFMenu`) and a top toolbar of category links and CRUD/print/help action icons (`SAIFMenuTop`) — on top of navigation and authorization data supplied entirely by external libraries. It contains no data access, no business-rule evaluation, and no direct calls into BOF business objects.

## Responsibilities
- Render a left-side navigation panel (`SAIFMenu`): favorites link list, collapsible application/category accordion (via `AjaxControlToolkit.Accordion`), and an optional "context value" text box (e.g., a claim-number field).
- Render a top toolbar (`SAIFMenuTop`): category-scoped navigation links plus a row of action icon buttons (Insert/Save/Delete/Edit/Cancel/Submit/Print/Preview/Email/Download/Calculate/Help/Set-Clear-Preferences), with per-button visibility/enabled state exposed via the nested `clsMenuButton` value object.
- Provide a shared building-block control (`SAIFImageButton`) that adds a "busy indicator" CSS class and client-side script for disabling other form controls while a postback is pending, used by every toolbar icon in `SAIFMenuTop` and independently reusable.
- Raise host-page-facing eventing (`MenuNavigate`, `ToolbarClick`, `DefaultOnSubmit`, `OnContextChanged`) so that actual navigation/redirection and business actions are performed by the consuming application rather than by this library.
- Cache and reuse a session-scoped `NavigationContext` (keyed by the current Windows-authenticated user) so both controls can share the same navigation data on a page.
- Persist lightweight UI state: per-button model state in `ViewState`, and the "Show Applications" expand/collapse preference via `SAIF.Presentation.clsPreferences` (per-user, `PrefScope.AppLevel`, key `"SHOWAPPS"`, group `"BOMENU"`).

## Component boundaries
- `SAIFMenu` (`System.Web.UI.Control`): owns rendering of the left navigation panel — favorites list, accordion of application categories, and context-value text box (`ContextViewStyleEnum`: `Normal`/`Read_Only`/`Hidden`). Does not itself perform navigation; raises `MenuNavigate`/`OnContextChanged`/`DefaultOnSubmit` for the host page, except for a hard-coded direct `Response.Redirect` to `/BusinessOnline/Changepassword.aspx` for the "Change Password" favorite.
- `SAIFMenuTop` (`WebControl`, `INamingContainer`): owns rendering of the top toolbar — category link row plus icon-button groups, gated by `ShowInsertSaveDelete`/`ShowPrintDownload` and each button model's `Visible`/`Enabled` state. Derives default button visibility/tooltips from the current page's `clsMenuAuthorizedItem` (via `NavigationContext.GetCurrentPage()`). Scans the page's control tree (`GetGrids`) for any control whose type name contains `"ULTRAWEBGRID"` to wire an `EndEdits()` call into toolbar `onclick` handlers, deliberately avoiding a direct Infragistics grid assembly reference.
- `SAIFMenuTop.clsMenuButton` (nested, `<Serializable()>`): value object describing one toolbar button's `Visible`, `Enabled`, `AccessKey`, `ImageURL`, `Tooltip`, `OneClick`, `DisableFormControlsOnClick`, `EnableIndicator` state; persisted in `ViewState`.
- `SAIFImageButton` (`System.Web.UI.WebControls.ImageButton`, `INamingContainer`): shared leaf control adding a busy-indicator CSS class (`SAIFImageButton`/`SAIFImageButtonIndicator`) and registering `/Resources/Scripts/Controls/ImageButton.js`; used as the visual/behavioral building block for every icon in `SAIFMenuTop`'s toolbar and reusable standalone.
- External collaborators consumed at the boundary (not owned by this library): [SAIF.Business.Menu](../saif-business-menu/overview.md) (`clsMenuAuthorizedItem`/`clsMenuAuthorizedItemCollection` — menu item, favorite, and category data plus authorization filtering); [SAIF.Presentation.Web.MVC](../saif-presentation-web-mvc/overview.md) (`ViewPageBase`, `NavigationContext`); [SAIF.Presentation](../saif-presentation/overview.md) (`clsPreferences`, `PrefScope`); ASP.NET runtime state (`HttpContext.Current.Session`/`User.Identity`/`Request.LogonUserIdentity`/`Request.Browser`).

## Interaction model
- Both `SAIFMenu` and `SAIFMenuTop` cast the hosting `Page` to `ViewPageBase` (from [SAIF.Presentation.Web.MVC](../saif-presentation-web-mvc/overview.md)) and subscribe to its `PreLoad` event (`Handles m_Page.PreLoad`), so these controls only function correctly on pages deriving from `ViewPageBase`*.
- Both controls lazily resolve navigation data through a private `GetNavigationData()` method that caches a `NavigationContext` object in `HttpContext.Current.Session("navdata")`, keyed off the current Windows-authenticated user (`HttpContext.Current.Request.LogonUserIdentity.Name`); this session cache is shared/reused across both controls when present together on a page.
- `SAIFMenuTop` looks up a sibling `SAIFMenu1` control on the page (if present) to snapshot its `ContextValue` into session before raising `MenuNavigate`, coupling the two controls' runtime behavior when both are placed on the same page.
- Neither control performs actual page navigation itself (aside from the hard-coded "Change Password" redirect in `SAIFMenu`): both raise `MenuNavigate(ApplicationPath, PageLink)` for the host application to handle redirection, and `ToolbarClick`/`DefaultOnSubmit` for host-specific CRUD/submit behavior.
- `SAIFImageButton` is a passive, reusable leaf: on `PreRender` it sets its CSS class and (if `EnableIndicator` is true) registers the shared client script once per page — it has no dependency on `SAIFMenu`/`SAIFMenuTop` beyond being constructed by `SAIFMenuTop.BuildMenuIcons` and looked up by `SAIFMenuTop.getImageButton(clsMenuButton)` (via `FindControl`, returning the existing child or `Nothing`), and used directly in markup elsewhere.
- Both `SAIFMenu.RenderControl` and `SAIFMenuTop.RenderControl` wrap rendering in `Try/Catch` blocks that swallow exceptions and write `ex.Message`/`ex.Source`/`ex.StackTrace` directly into the HTML output stream instead of re-throwing or logging*.

## Architecture diagram
The following diagram shows the three components in this library, their shared external collaborators, and the host-page boundary.

```mermaid
flowchart TD
	Host["Host ASPX page<br>(ViewPageBase-derived)"] --> SAIFMenu["SAIFMenu<br>(left nav panel)"]
	Host --> SAIFMenuTop["SAIFMenuTop<br>(top toolbar)"]
	SAIFMenuTop --> SAIFImageButton["SAIFImageButton<br>(icon button)"]
	SAIFMenu -.->|shares session cache| SAIFMenuTop
	SAIFMenu --> NavCtx["NavigationContext<br>(SAIF.Presentation.Web.MVC,<br>cached in Session)"]
	SAIFMenuTop --> NavCtx
	NavCtx --> MenuBiz["clsMenuAuthorizedItem(Collection)<br>(SAIF.Business.Menu)"]
	SAIFMenu --> Prefs["clsPreferences<br>(SAIF.Presentation)"]
	SAIFMenu --> Ajax["AjaxControlToolkit.Accordion<br>(Libs\AjaxControlToolkit.dll)"]
	SAIFMenu -->|MenuNavigate/OnContextChanged| Host
	SAIFMenuTop -->|MenuNavigate/ToolbarClick| Host
```

## Sequence diagram
The following diagram shows the primary request/response sequence for a page rendering both controls and the user clicking a favorite link.

```mermaid
sequenceDiagram
	participant Client
	participant Host as Host page (ViewPageBase)
	participant Menu as SAIFMenu
	participant NavCtx as NavigationContext
	participant MenuBiz as clsMenuAuthorizedItem (SAIF.Business.Menu)
	Client->>Host: Request page
	Host->>Menu: PreLoad / OnLoad
	Menu->>NavCtx: GetNavigationData() (cached in Session)
	NavCtx->>MenuBiz: Retrieve authorized favorites/categories
	MenuBiz-->>NavCtx: clsMenuAuthorizedItemCollection
	NavCtx-->>Menu: Navigation data
	Menu-->>Host: Rendered favorites/accordion HTML
	Client->>Menu: Click favorite link
	Menu->>Host: Raise MenuNavigate(ApplicationPath, PageLink)
	Host-->>Client: Redirect to target page
```

## Design constraints
- Requires Windows/Integrated authentication: both controls resolve the current user via `HttpContext.Current.Request.LogonUserIdentity.Name`, implying the hosting application relies on IIS integrated authentication rather than forms authentication*.
- Requires the hosting page to derive from `ViewPageBase` ([SAIF.Presentation.Web.MVC](../saif-presentation-web-mvc/overview.md)); the controls cast `Page` to this type and subscribe to its `PreLoad` event*.
- No business-rule evaluation or authorization logic is native to this library — all menu-item/favorite authorization is consumed as-is from `clsMenuAuthorizedItem`/`clsMenuAuthorizedItemCollection` ([SAIF.Business.Menu](../saif-business-menu/overview.md)), which this library trusts and renders without further checks**.
- `SAIFImageButton` is decorated with `AspNetHostingPermissionAttribute` (`SecurityAction.Demand` and `SecurityAction.InheritanceDemand`, `Level:=AspNetHostingPermissionLevel.Minimal`), a legacy Code Access Security constraint limiting the minimum trust level for medium/partial-trust IIS hosting.
- `SAIFMenuTop` deliberately avoids a direct Infragistics grid assembly reference, instead detecting `UltraWebGrid` controls by scanning the page's control tree for type names containing `"ULTRAWEBGRID"` (per an in-source comment, "I don't want to reference infragistics").
- Both controls' `RenderControl` swallow rendering exceptions and write exception message/source/stack trace directly into the HTML response instead of failing safely or logging — a potential information-disclosure risk in production*.
- Static resource paths (`/Resources/MenuImages/*.gif|png`, `/Resources/Scripts/Controls/ImageButton.js`) and the "Change Password" redirect target (`/BusinessOnline/Changepassword.aspx`) are hard-coded site-relative paths, assumed to be deployed by the consuming web application rather than this assembly*.
- Rendering is built imperatively in code (`CreateChildControls`/`RenderControl` overrides) rather than via markup/templates, for both `SAIFMenu` and `SAIFMenuTop`.
- No database, security-model, or configuration documentation is produced for this library directly: it consumes [SAIF.Business.Menu](../saif-business-menu/overview.md) (which owns its own menu-authorization security model) as an external dependency rather than duplicating that model 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)
- [Control catalog](control-catalog.md)
- [Configuration](configuration.md)
- [Security and authorization](security-authorization.md)
- [API reference](api/index.md)

## Sources
- `SAIF.Presentation.Web.Controls.V2.Menu\SAIF.Presentation.Web.Controls.V2.Menu.vbproj`
- `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.Controls.V2.Menu\packages.config`
