Skip to content

Page/control lifecycle initialization

clsControllerBase.Initialize() is the central orchestration point invoked at the start of every request processed by a page or control derived from ViewPageBase/ViewControlBase. It runs the session-timeout check, both authorization gates, and the concrete model's pre-initialization hook, in a fixed order with no bypass paths.

Field Value
Operation ID OP-MVC-001
Trigger ViewPageBase.Page_Init / ViewControlBase.Page_Init event, via the concrete clsFactoryBase.GetController()
Inputs Current HttpContext (session, query string, request path)
Outputs Populated Model, Session("navdata"), possible redirect/response termination
Primary components clsControllerBase.Initialize
Entry point SAIF.Presentation.Web.MVC\clsControllerBase.vb

Steps

  1. Check IsSessionTimedOut (IsPostBack And Session.IsNewSession) (BR-MVC-001).
  2. If timed out: redirect to "/" & ApplicationName with a MSG query-string parameter identifying the timeout for internal clients (per the local IsInsideClient classification, BR-MVC-008), or to /OnlineLogin/LoginScreen.aspx (clearing the SAIFAUTH cookie) for external/online clients, then Response.End().
  3. On failure: a ThreadAbortException raised by Response.Redirect is swallowed via Thread.ResetAbort().
  4. If __SAIFPID is present on the query string, seed ViewPage.ViewID from it.
  5. Call SecurityCheck() (BR-MVC-003) — verifies a clsSecurityPrincipal exists on Model.Context, or challenges/denies the request.
  6. If not authenticated and clsEnvironment.InternalAddress(Request.UserHostAddress) (an external SAIF.BOF.Framework dependency, distinct from the local IsInsideClient property behind BR-MVC-008) returns True: issue an HTTP 401 with WWW-Authenticate: NTLM/Basic challenge headers and end the response.
  7. If not authenticated and clsEnvironment.InternalAddress returns False: throw Exception("Not Authorized.").
  8. If Session("navdata") is empty, construct a new NavigationContext(Model.Context.UserID).
  9. This delegates to SAIF.Business.Menu collections (clsMenuAuthorizedItemCollection, clsApplicationCodeCollection, clsMenuCategoryCodeCollection) retrieved via an Oracle data layer (clsMSOracleDataLayer, constructed with EnvironmentConfigKeys.OracleDatabase).

Origin: Build a user's authorized menu (SAIF.Business.Menu, OP-MENU-001) — the menu/authorization data retrieval logic itself (SQL/Criteria implementation) lives in SAIF.Business.Menu, outside this library's scope; NavigationContext only supplies the Oracle connection context and consumes the resulting collections. Its applicable ordered logic: 1. Accept IDataPortalInfo and the current MenuUser (Model.Context.UserID), then choose the user-scoped SQL retrieval for authorized menu items. 2. Join the menu item, menu security, menu security user, menu page, application code, and menu category code tables so only matching user/item group intersections survive. 3. Add the public-item branch that returns rows with no menu security assignment (unsecured menu items are visible by default). 4. Union active favorites for the user-scoped query. 5. Materialize each row into clsMenuAuthorizedItem, then expose filtered views such as Favorites, ApplicationItems, AppItemsByCategory, and SecuredAppItems — this is the clsMenuAuthorizedItemCollection that NavigationContext.IsMenuItem() queries in step 5 below. 5. Call RedirectUnauthorizedUsers() (BR-MVC-002) — calls NavigationContext.IsMenuItem(currentApp, currentItem). - If not authorized: clear Session("navdata") and redirect to /OnlineLogin/LoginScreen.aspx; log a warning trace. 6. Model.Pre_Init() — lazily runs the concrete model's Initialize() override exactly once, and loads clsPreferences for the current user/application via the SAIF.Presentation project reference. 7. Load() — overridable hook invoked for the concrete controller; no default behavior in this library. 8. If the query string has keys, call HandleQuerystring (abstract/overridable hook) via ProcessQueryStrings(). 9. If Request.UrlReferrer is present, call CheckContext(UrlReferrer.LocalPath). - This delegates to the Cross-application context hand-off operation.

Process flow

flowchart TD
    Start([Page_Init]) --> Timeout{Session timed out?}
    Timeout -->|Yes| Redirect1([Redirect + Response.End])
    Timeout -->|No| SecCheck[SecurityCheck]
    SecCheck --> Auth{Authenticated?}
    Auth -->|No, clsEnvironment.InternalAddress true| Challenge([401 NTLM/Basic challenge])
    Auth -->|No, clsEnvironment.InternalAddress false| Deny([Throw Not Authorized])
    Auth -->|Yes| NavBuild{Session navdata present?}
    NavBuild -->|No| BuildNav[Construct NavigationContext]
    NavBuild -->|Yes| MenuCheck
    BuildNav --> MenuCheck{IsMenuItem authorized?}
    MenuCheck -->|No| Redirect2([Clear navdata, redirect to LoginScreen.aspx])
    MenuCheck -->|Yes| PreInit[Model.Pre_Init]
    PreInit --> Load[Load hook]
    Load --> QS{Query string present?}
    QS -->|Yes| HandleQS[HandleQuerystring]
    QS -->|No| Referrer
    HandleQS --> Referrer{UrlReferrer present?}
    Referrer -->|Yes| CheckContext([CheckContext: hand-off])
    Referrer -->|No| End([Initialization complete])
    CheckContext --> End

Failure and edge-case behavior

  • A ThreadAbortException from any Response.Redirect/Response.End call in this operation is caught and suppressed via Thread.ResetAbort(), so it never surfaces as an unhandled error.
  • If SecurityCheck() throws Exception("Not Authorized."), that exception propagates out of Initialize() and is ultimately caught by ViewPageBase.Page_Error → Error handling.
  • No bypass path exists for any controller derived from clsControllerBase — both authorization gates run unconditionally on every request.

Sources

  • SAIF.Presentation.Web.MVC\clsControllerBase.vb
  • SAIF.Presentation.Web.MVC\NavigationContext.vb