---
title: Resolve navigation and authorized menu context
summary: Loads a user's authorized menu items from Oracle and answers navigation/authorization questions in-memory.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-17
library: SAIF.Presentation.Web.Core.Infragistics111
reference_type: package
operation_id: OP-CORE-006
trigger: Construction of a NavigationContext for a signed-in user, then per-request navigation queries
---

# Resolve navigation and authorized menu context

`NavigationContext` is the only type in this library that reaches a database. On construction it loads the current user's authorized menu items from Oracle through `SAIF.Business.Menu`, then answers all subsequent navigation and authorization questions (current page, item lookup, sequence, menu membership) purely from the in-memory authorized set.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-CORE-006 |
| **Trigger** | Construction of a `NavigationContext` for a signed-in user, then per-request navigation queries |
| **Inputs** | User ID (`inUser`), `MENU_ENVIRONMENT` app setting, `HttpContext.Current.Request.ApplicationPath` / `RawUrl` |
| **Outputs** | `clsMenuAuthorizedItem` instances, menu item sequence numbers, menu-membership booleans |
| **Primary components** | `NavigationContext` (constructor, `GetItem`, `GetCurrentItem`, `GetCurrentPage`, `GetItemSeq`, `IsMenuItem`) |
| **Entry point** | `SAIF.Presentation.Web.Core.Infragistics111/NavigationContext.vb` |

## Steps

1. Construct `clsMSOracleDataLayer` with the fixed DB user name `MENU` and the environment name read from the `MENU_ENVIRONMENT` app setting. ([BR-CORE-017](../business-rules.md#br-core-017-menu-data-is-always-read-as-the-fixed-database-user-menu-against-the-environment-named-by-the-menu_environment-app-setting))
2. Obtain an `IDataPortalInfo` from the data layer (`m_DAL.DataPortalInfo()`).
3. Call `clsMenuAuthorizedItemCollection.GetMenuAuthorizedItems(dpi, user.Trim.ToUpper)` to load the authorized menu items for the user. ([BR-CORE-018](../business-rules.md#br-core-018-user-ids-are-trimmed-and-upper-cased-before-authorized-item-lookup), [BR-CORE-019](../business-rules.md#br-core-019-navigation-answers-are-restricted-to-the-menu-items-the-user-is-authorized-for))
   - > **Origin**: The SQL that retrieves the authorized items executes inside `SAIF.Business.Menu` (local project reference), not in this library. See that library's `operations/resolve-navigation-and-authorized-menu-context.md`-equivalent page for the retrieval logic.
4. On first access, `ApplicationCodes` / `MenuCategories` lazily load and cache the active application codes and menu category codes in `Static` locals. ([BR-CORE-020](../business-rules.md#br-core-020-application-codes-and-menu-category-codes-are-loaded-once-and-cached-for-the-life-of-the-process))
   - > **Origin**: Delegates to `clsApplicationCodeCollection.GetActiveApplicationCodes` and `clsMenuCategoryCodeCollection.GetMenuCategoryCodes` in `SAIF.Business.Menu`.
   - Each collection is fetched once per process; subsequent calls reuse the cached value.
5. For lookups, resolve the current application code by stripping `/` from `Request.ApplicationPath` and matching it with `ApplicationCodes.ItemByAppPath`.
   - If no application code resolves: return `Nothing` / `0`. ([BR-CORE-021](../business-rules.md#br-core-021-when-the-current-application-path-does-not-map-to-a-known-application-code-navigation-lookups-return-no-item))
6. For `GetCurrentItem` / `GetCurrentPage`, derive the page link from `Request.RawUrl.Substring(Request.ApplicationPath.Length + 1)`.
   - Attempt an exact match first (`ItemExact` / `FindPageExact`).
   - If no exact match: fall back to the fuzzy match (`Item` / `FindPage`). ([BR-CORE-022](../business-rules.md#br-core-022-page-and-item-lookups-prefer-an-exact-link-match-and-fall-back-to-a-partial-match))
7. `GetItem` with `inAnyApp = True` bypasses application-code scoping and searches by category across all applications. ([BR-CORE-023](../business-rules.md#br-core-023-getitem-with-inanyapp-true-searches-by-category-across-all-applications-ignoring-the-current-application-code))

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([NavigationContext constructed]) --> S1[New clsMSOracleDataLayer MENU, MENU_ENVIRONMENT]
	S1 --> S2[Obtain IDataPortalInfo]
	S2 --> S3[GetMenuAuthorizedItems trim/upper user]
	S3 --> S4{First access to ApplicationCodes/MenuCategories?}
	S4 -->|Yes| S5[Load and cache in Static locals]
	S4 -->|No| S6[Reuse cached collections]
	S5 --> Query([Ready for navigation queries])
	S6 --> Query
	Query --> Q1{App path resolves to a code?}
	Q1 -->|No| Nothing([Return Nothing / 0])
	Q1 -->|Yes| Q2{Exact link match found?}
	Q2 -->|Yes| Exact([Return exact match])
	Q2 -->|No| Fuzzy([Fall back to fuzzy match])
```

## Failure and edge-case behavior
- `NavigationContext` never re-validates that the supplied user name matches the authenticated identity — that responsibility sits with callers.*
- When the application-code cache and the authorized-item set disagree (e.g. after a code is deactivated mid-process), stale application codes persist until a process recycle. ([BR-CORE-020](../business-rules.md#br-core-020-application-codes-and-menu-category-codes-are-loaded-once-and-cached-for-the-life-of-the-process))

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `SAIF.Presentation.Web.Core.Infragistics111/NavigationContext.vb`
