Cross-application navigation¶
Navigate/Navigate2 implement outbound navigation from the current page, either within the same SAIF application or across to a different one. Cross-application navigation persists in-memory context values to the shared Context table so the target application can retrieve them on arrival (see Cross-application context hand-off).
| Field | Value |
|---|---|
| Operation ID | OP-MVC-003 |
| Trigger | Explicit call to clsControllerBase.Navigate(TargetApp, TargetView) or the new-model overload Navigate2(TargetApp, TargetView) from a concrete controller |
| Inputs | Target application/view, popup flags, optional new-model GUID |
| Outputs | HTTP redirect or window.open client script; persisted context row(s) in Context |
| Primary components | clsControllerBase.Navigate, clsControllerBase.Navigate2, clsContext.SaveContext |
| Entry point | SAIF.Presentation.Web.MVC\clsControllerBase.vb |
Steps¶
- Compute
SourceAppfrom the currentApplicationPath; buildNavTarget(absolute URL, path-rooted, or/{TargetApp}/{TargetView}). - Stash
targetView/targetApp/sourceApp/sourceViewintoModel.Context(in-memory, not yet persisted). - If
SourceApp <> TargetApp(cross-application navigation) (BR-MVC-005): - If
SupportsMultiModel, also stash the currentViewIDunder__SAIFPID. - Unless the session has timed out, call
Model.Context.SaveContext(SessionID):- Executes SQL-MVC-004 (
DELETE FROM Context WHERE AppName=@AppName AND SessionID=@SessionID) against Context. - Executes SQL-MVC-001 once per stored context key (an
INSERT INTO Contextstatement supplying the application name, session ID, context key, and context value) against Context.
- Executes SQL-MVC-004 (
- If
SourceApp = TargetApp(same-application navigation), store the (possibly new)ViewID/model GUID intoSession[__SAIFPID]instead of persisting to the database. - If
Popupis true, register a client startup script that callswindow.openwith the computed target URL, window name, and popup features, plus an optional focus-blur script. - Otherwise:
Response.Redirect(NavTarget)andResponse.End(). - On failure:
ThreadAbortExceptionis swallowed viaThread.ResetAbort(). Navigate2additionally, before delegating toNavigate:- Requires
SupportsMultiModel(BR-MVC-004); throwsApplicationException("Navigate2 only supported with Multiple Model configuration.")otherwise. - Creates a brand-new
clsModelBasevia the factory, assigns a freshclsSecurityPrincipal, runsPre_Init(). - Invokes the overridable
OnNewModel(newModel, newViewData)hook to let the concrete controller copy state from the old model to the new one. - On success, copies existing
ViewDataentries into the new view-data dictionary, stores the new model/view-data inSessionunder a new GUID, then delegates toNavigate(inTargetApplication, inTargetView, inNewModel:=NewGuid).
Process flow¶
flowchart TD
Start([Navigate called]) --> Compute[Compute SourceApp / NavTarget]
Compute --> StashCtx[Stash targetView/targetApp/sourceApp/sourceView in Model.Context]
StashCtx --> CrossApp{SourceApp <> TargetApp?}
CrossApp -->|Yes| SaveCtx[SaveContext: delete then insert rows]
CrossApp -->|No| SessionStore[Store ViewID in Session]
SaveCtx --> PopupCheck{Popup?}
SessionStore --> PopupCheck
PopupCheck -->|Yes| Script([Register window.open startup script])
PopupCheck -->|No| Redirect([Response.Redirect + Response.End])
Failure and edge-case behavior¶
Navigate2throwsApplicationExceptionimmediately ifSupportsMultiModelisFalse— no partial state is created.SaveContext's delete-then-insert has no rowcount/contention validation; a concurrentSaveContextcall for the same application/session could interleave.ThreadAbortExceptionfromResponse.Redirect/Response.Endis caught and suppressed in bothNavigateandHandleErrors.
Related documentation¶
Sources¶
- SAIF.Presentation.Web.MVC\clsControllerBase.vb
- SAIF.Presentation.Web.MVC\clsContext.vb