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¶
Enforce.ArgumentNotNull(filterContext, "filterContext")(BR-01).- Cast
ViewData.ModeltoMenuViewModelBase; skip all menu work when the cast yields null (BR-06). - Resolve the menu from session: when
Session["BusinessOnlineMenu"]is null, callmenuService.GetBusinessOnlineMenu(User.Identity.Name)(delegates to OP-12), map throughMappers.MapMenuViewModel(OP-13), and cache the result in session; otherwise reuse the cachedMenuViewModel(BR-21). - Set
model.Menu.CurrentApplicationNamefromRequest.Url.ApplicationName(). - Compute
model.Menu.CurrentItemIdthroughGetCurrentItemId(BR-22). - When the absolute path minus
/equals the current application name, treat the page link asHome/Index; otherwise strip the/{app}/prefix from the absolute path. - When the resulting link contains no
/, append/Index. - Split on
/; when there are three or more segments keep only the first two — this drops route ids from the lookup key (BR-24). - Re-append the original query string.
- Return the
PageIdof the first menu item whoseApplicationNamematches the current application (case-insensitive) and whosePageLinkmatches the computed link (case-insensitive), or""when no match exists (BR-25). - Set
model.Menu.IsMenuExpanded = true— the menu is always rendered expanded. - Set
model.Menu.MenuCategoryfrom the derived controller's abstractMenuCategoryproperty. - Set
model.Menu.IsExternalUserfromApplicationUser.IsExternal, whereApplicationUserlazily callsUserProfileService.GetCurrentUser()and memoizes it for the request (BR-23). - 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.
Related documentation¶
Sources¶
src/Web.Mvc/Controllers/MenuControllerBase.cs