Skip to content

Build and attach the Business Online menu

Populate the current view model's menu, decorating it with the active item, category, and user status. Trigger: After every action on a controller derived from MenuControllerBase.

Field Value
Operation ID OP-11
Trigger After every action on a controller derived from MenuControllerBase
Inputs ViewData.Model, User.Identity.Name, request URL, HttpContext.Session["BusinessOnlineMenu"]
Outputs MenuViewModelBase.Menu fully populated
Primary components MenuControllerBase.OnActionExecuted(ActionExecutedContext), private Menu property, private GetCurrentItemId
Entry point src/Web.Mvc/Controllers/MenuControllerBase.cs

Steps

  1. Enforce.ArgumentNotNull(filterContext, "filterContext") (BR-01).
  2. Cast ViewData.Model to MenuViewModelBase; skip all menu work when the cast yields null (BR-06).
  3. Resolve the menu from session: when Session["BusinessOnlineMenu"] is null, call menuService.GetBusinessOnlineMenu(User.Identity.Name) (delegates to OP-12), map through Mappers.MapMenuViewModel (OP-13), and cache the result in session; otherwise reuse the cached MenuViewModel (BR-21).
  4. Set model.Menu.CurrentApplicationName from Request.Url.ApplicationName().
  5. Compute model.Menu.CurrentItemId through GetCurrentItemId (BR-22).
  6. When the absolute path minus / equals the current application name, treat the page link as Home/Index; otherwise strip the /{app}/ prefix from the absolute path.
  7. When the resulting link contains no /, append /Index.
  8. Split on /; when there are three or more segments keep only the first two — this drops route ids from the lookup key (BR-24).
  9. Re-append the original query string.
  10. Return the PageId of the first menu item whose ApplicationName matches the current application (case-insensitive) and whose PageLink matches the computed link (case-insensitive), or "" when no match exists (BR-25).
  11. Set model.Menu.IsMenuExpanded = true — the menu is always rendered expanded.
  12. Set model.Menu.MenuCategory from the derived controller's abstract MenuCategory property.
  13. Set model.Menu.IsExternalUser from ApplicationUser.IsExternal, where ApplicationUser lazily calls UserProfileService.GetCurrentUser() and memoizes it for the request (BR-23).
  14. Call base.OnActionExecuted(filterContext), which runs OP-02.

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start([Action executed])
    Guard[Guard filterContext]
    Cast[Cast ViewData.Model to MenuViewModelBase]
    Skip([Skip menu work])
    Cache{Menu cached in session?}
    Fetch[Fetch and map menu]
    Reuse[Reuse cached menu]
    Item[Compute CurrentItemId]
    User[Resolve IsExternalUser]
    EndOk([Continue])
    Start --> Guard
    Guard --> Cast
    Cast -->|No match| Skip
    Cast -->|Match| Cache
    Cache -->|Miss| Fetch
    Cache -->|Hit| Reuse
    Fetch --> Item
    Reuse --> Item
    Item --> User
    User --> EndOk
    Skip --> EndOk

Failure and edge-case behavior

  • No unexpected failure paths beyond argument-guard exceptions and delegated dependency behavior were identified for this operation.

Sources

  • src/Web.Mvc/Controllers/MenuControllerBase.cs