Skip to content

SAIF.Framework.Web.Mvc architecture

SAIF.Framework.Web.Mvc is a presentation-tier framework library sitting between ASP.NET MVC 5 / Web API 2 and the SAIF core/data framework packages; it contains no application logic of its own and no entry point, and consuming applications inherit its controller bases, apply its filters, and call its Autofac registration helper during Application_Start (Architecture findings § Layer position).

Responsibilities

  • Provide per-request web-context resolution, cross-application navigation, and menu decoration for derived controllers through the controller bases in src/Web.Mvc/Controllers/ (Architecture findings § Components and responsibility boundaries).
  • Centralize exception logging/redirect and role-based authorization through the action filters in src/Web.Mvc/ActionFilters/ (Architecture findings § Components and responsibility boundaries).
  • Cache web contexts in HttpContext.Session and proxy to the remote WCF context service through the web context services in src/Web/ (Architecture findings § Components and responsibility boundaries).
  • Query and shape the Business Online menu through the menu services in src/Web.Mvc/Classes/ (Architecture findings § Components and responsibility boundaries).
  • Bridge domain validation results into ModelStateDictionary and project them back out as JSON-friendly ErrorViewModel[] through the model-state helpers (Architecture findings § Components and responsibility boundaries).
  • Supply a fluent builder/factory framework for server-rendered components (Html.SAIF().Toolbar()) through the UI component framework in src/Web.Mvc/UI/ (Architecture findings § Components and responsibility boundaries).
  • Emit menu, web-context form, label, linked-dropdown, and text-counter markup carrying js-bo-* / data-* client hooks through the HTML helper extensions (Architecture findings § Components and responsibility boundaries).
  • Provide a single registration entry point (AutofacExtensions.RegisterCommonDependencies) wiring MVC/Web API, NHibernate, menu, web context, and environment services for the consuming application's composition root (Architecture findings § Components and responsibility boundaries).

Component boundaries

  • Controller bases (src/Web.Mvc/Controllers/): owns MVC action-filter lifecycle hooks; delegates context storage to IWebContextService (Architecture findings § Components and responsibility boundaries).
  • Action filters (src/Web.Mvc/ActionFilters/): owns cross-cutting request interception; delegates to ILogService, IUserProfileService, IEnvironmentService (Architecture findings § Components and responsibility boundaries).
  • Web context services (src/Web/): owns session caching and endpoint construction; the WCF channel itself is external (Architecture findings § Components and responsibility boundaries).
  • Menu services (src/Web.Mvc/Classes/): owns filtering/ordering/mapping; delegates persistence to IRepository<BusinessOnlineMenuItem> (NHibernate) (Architecture findings § Components and responsibility boundaries).
  • Model-state helpers (ModelStateWrapper.cs, ModelStateExtensions.cs): owns key translation between view-model grid paths and domain collection paths (Architecture findings § Components and responsibility boundaries).
  • UI component framework (src/Web.Mvc/UI/): owns HTML emission; contains no data access (Architecture findings § Components and responsibility boundaries).
  • HTML helper extensions (src/Web.Mvc/Extensions/, src/Web.Mvc/UI/Extensions/): owns server side only; the paired client-side JavaScript lives outside this repository** (Architecture findings § Components and responsibility boundaries, marked ** in source).
  • View models (src/Web.Mvc/ViewModels/): pure data carriers (Architecture findings § Components and responsibility boundaries).
  • Composition (AutofacExtensions.cs): owns registration only; ContainerBuilder.Build() (composition root) is the consuming application's responsibility (Architecture findings § Components and responsibility boundaries).

Interaction model

  • Request enters an application controller derived from MenuControllerBase → WebContextControllerBase → ControllerBase → System.Web.Mvc.Controller (Architecture findings § Data and control flow, step 1).
  • WebContextControllerBase.OnActionExecuting resolves the web context (TempData → form/query → referrer-session → new) and stamps it into the IIS log (Architecture findings § Data and control flow, step 2).
  • The action executes; unhandled exceptions are intercepted by HandleExceptionAttribute; unauthorized access is intercepted by SaifAuthorizeAttribute before the action runs (Architecture findings § Data and control flow, step 3).
  • WebContextControllerBase.OnActionExecuted copies context id/value into any WebContextViewModelBase model; MenuControllerBase.OnActionExecuted then decorates any MenuViewModelBase model with the session-cached menu (Architecture findings § Data and control flow, step 4).
  • Razor views call Html.RenderMenu, Html.RenderWebContext, and Html.SAIF().Toolbar() to emit markup (Architecture findings § Data and control flow, step 5).
  • Navigate posts drive cross-application redirects, persisting context through the WCF service when the target application differs (Architecture findings § Data and control flow, step 6).
  • Cross-cutting concerns: exception handling (HandleExceptionAttribute logs and redirects to Constants.ErrorUrl; AJAX requests are logged but not redirected), authorization (SaifAuthorizeAttribute), state (HttpContext.Session keys WebContextRepository, ContextServiceUrl, BusinessOnlineMenu; TempData key WebContextId), and service location (property injection on filters supplied by Autofac's MVC filter provider) (Architecture findings § Cross-cutting concerns).
  • WebContextServiceClient derives from DisposableClientBase<IWebContextService> (SAIF.Services.WCF.ClientProxies, SAIF.Framework.Core)†. Per inherited framework context, DisposableClientBase<TChannel> is an abstract WCF client-proxy base over System.ServiceModel.ClientBase<TChannel> that accepts a Binding and EndpointAddress in its constructor and implements IDisposable.Dispose() to close the channel gracefully, falling back to Abort() when the channel is faulted or Close() throws — so WebContextServiceClient inherits fault-safe WCF teardown rather than implementing its own disposal logic (Framework type classification; legends chat, SAIF.Framework.Core, doc-type api)†.

Architecture diagram

The following diagram shows high-level component interactions.

flowchart TD
    App[Consuming MVC application] --> Ctrl[Controller bases]
    App --> Filters[Action filters]
    App --> Compose[AutofacExtensions composition]
    Ctrl --> WebCtxSvc[WebContextService]
    Ctrl --> MenuSvc[MenuService]
    Filters --> Core[SAIF.Framework.Core services]
    WebCtxSvc --> Session["(HttpContext.Session)"]
    WebCtxSvc --> WCF[WCF WebContextService remote]
    MenuSvc --> Repo[IRepository BusinessOnlineMenuItem]
    Repo --> NHibernate[SAIF.Framework.Data.NHibernate]
    NHibernate --> Oracle["(Oracle database)"]
    Views[Razor views] --> UI[UI component framework and HTML helpers]
    UI --> Ctrl

Sequence diagram

The following diagram shows the primary request/response sequence.

sequenceDiagram
    participant Client
    participant Controller as MenuControllerBase/WebContextControllerBase
    participant WebContextService
    participant WCF as WCF WebContextService (remote)
    Client->>Controller: HTTP request
    Controller->>WebContextService: resolve web context (Get)
    WebContextService->>WCF: fetch context if not session-cached
    WCF-->>WebContextService: web context
    WebContextService-->>Controller: web context
    Controller-->>Client: rendered view (menu + web context decorated)

Design constraints

  • No internal <ProjectReference> exists; all internal SAIF dependencies (SAIF.Framework.Core, SAIF.Framework.Data.NHibernate) are consumed as NuGet packages (Dependencies § Internal project references).
  • ControllerBase, ViewModelBase, and IEnumerableExtensions are empty extension points reserved for future behavior with no current members (Architecture findings § Architectural observations).
  • NavigationItemBuilder<TItem, TBuilder>.Action and .Route overloads are declared but return this without recording routing values — routing configuration through the fluent toolbar API is a no-op in the current code (Architecture findings § Architectural observations).
  • Toolbar.WriteHtml calls only base.WriteHtml(writer), and ViewComponentBase.WriteHtml is an empty virtual — rendering a Toolbar currently emits no markup (Architecture findings § Architectural observations).
  • HtmlElement fully implements IHtmlNode but is not consumed by any type in this library — it is a public building block for consumers* (Architecture findings § Architectural observations, marked * in source).
  • The library ships as C# source files packaged into the consumer's src folder (the nuspec's <file> element maps src="**\*.cs" to target="src") rather than a compiled assembly, so consuming applications compile this library's source directly (Package findings).
  • No class in this library derives from a SAIF Business Object Framework base class (clsBusinessBase, clsBusinessCollectionBase) or implements IBusinessCriteria (Framework type classification).

Note: Statements marked with † are derived from dependency library documentation via the Legends CLI. Statements marked with * were inferred from code structure or contextual evidence. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • src/SAIF.Framework.Web.Mvc.csproj
  • src/SAIF.Framework.Web.Mvc.nuspec
  • src/Web.Mvc/Controllers/ControllerBase.cs
  • src/Web.Mvc/Controllers/WebContextControllerBase.cs
  • src/Web.Mvc/Controllers/MenuControllerBase.cs
  • src/Web.Mvc/ActionFilters/HandleExceptionAttribute.cs
  • src/Web.Mvc/ActionFilters/SaifAuthorizeAttribute.cs
  • src/Web/WebContextService.cs
  • src/Web/WebContextServiceClient.cs
  • src/Web.Mvc/Classes/MenuService.cs
  • src/Web.Mvc/Classes/ModelStateWrapper.cs
  • src/Web.Mvc/Extensions/ModelStateExtensions.cs
  • src/Web.Mvc/Extensions/AutofacExtensions.cs
  • src/Web.Mvc/UI/ViewComponentBase.cs
  • src/Web.Mvc/UI/Toolbar/Toolbar.cs
  • src/Web.Mvc/UI/NavigationItemBuilder.cs
  • src/Web.Mvc/UI/HtmlElement.cs
  • Inherited framework context retrieved via Legends CLI (legends chat "What are the public members and architecture of DisposableClientBase in SAIF.Framework.Core?" --library SAIF.Framework.Core --doc-type api --docgen --raw): SAIF.Framework.Core API documentation for SAIF.Services.WCF.ClientProxies.DisposableClientBase<TChannel>