---
title: SAIF.Framework.Web.Mvc architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-09-17
library: SAIF.Framework.Web.Mvc
reference_type: package
---

# 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.

```mermaid
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.

```mermaid
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).

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [API reference](api/index.md)

> **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>`
