MVC Architecture
Introduction
Damsy ERP uses ASP.NET MVC 5 with a hybrid structure: root controllers handle login, dashboard, and shared masters, while MVC Areas isolate each business module (Payroll, Bills, Stock, and others). Each Area has its own controllers, views, and typically a dedicated layout shell.
Purpose
This page documents how the presentation layer is organized so you can add screens, wire navigation, and apply the correct layout and asset bundle for a module.
When to Use
Consult this page when you:
- Add a new controller or view inside a module
- Choose or create a layout for a new Area screen
- Link from the dashboard or sidebar to a module route
- Debug routing issues (
/Payroll/...vs/Login/...)
How It Works
Root vs Area structure
Registered Areas
Each Area is registered via *AreaRegistration.cs under DamsyERP.UI/Areas/<AreaName>/ and discovered at startup by AreaRegistration.RegisterAllAreas().
| Area folder | Route prefix | Primary dashboard controller |
|---|---|---|
| Payroll | /Payroll/... | PayrollDashboardController |
| Registration | /Registration/... | RegistrationDashboardController |
| Bills | /Bills/... | BillsDashboardController |
| Stock | /Stock/... | StockDashboardController |
| Sales | /Sales/... | SalesDashboardController |
| ESS | /ESS/... | EssDashboardController |
| Adminisration | /Adminisration/... | UserDashBoardController |
| AttendancePunching | /AttendancePunching/... | AttendanceDashboardController |
| Operation | /Operation/... | OperationDashboardController |
| ManagmentDashBoard | /ManagmentDashBoard/... | ManagmentDashBoardController |
| ContractedRates | /ContractedRates/... | ContractedDashboardController |
| VerificationAndApproval | /VerificationAndApproval/... | VerificationApprovalDashboardController |
Area URL pattern:
{area}/{controller}/{action}/{id}
Controllers
Root controllers (DamsyERP.UI/Controllers/):
LoginController— authentication, module redirect, logoutDashboardController— home tile hub after loginEmployeeMController— shared employee master (used across modules viaSession["Module"])ManageErrorController— global error pages
Area controllers live under Areas/<Area>/Controllers/ and follow standard MVC naming (PayrollDashboardController, CreateBillsController, etc.).
Typical controller action pattern:
public ActionResult Index()
{
if (string.IsNullOrEmpty(Convert.ToString(Session["CompID"])))
return RedirectToAction("UserLogin", "Login", new { Area = "" });
// DAL calls, ViewBag/ViewData, return View()
}
Views and layouts
Razor views are co-located with their Area:
Areas/Payroll/Views/
PayrollDashboard/Index.cshtml
Shared/_LayoutPayroll.cshtml
ManageError/Index.cshtml
Module layouts wrap every page in a consistent shell (sidebar, header, module CSS):
| Module | Layout file |
|---|---|
| Payroll | _LayoutPayroll.cshtml |
| Registration | _RegistrationLayout.cshtml |
| Bills | _BillsLayout.cshtml |
| Stock | _StockLayout.cshtml |
| ESS | _EssLayout.cshtml |
| Attendance Punching | _AttPunchingLayout.cshtml |
| Management Dashboard | _ManagmentDashBoardLayout.cshtml |
| Contracted Rates | _ContractedRatesLayout.cshtml |
| Verification & Approval | `_LayoutVerificationApproval.cshtml |
Root shared partials (Views/Shared/):
_Layout.cshtml— base shell for login and dashboard_HeaderLayout.cshtml— header chrome_SidebarBrand.cshtml,_SidebarMenuSearch.cshtml— sidebar branding and search
Views set layout in _ViewStart.cshtml or per-view:
@{
Layout = "~/Areas/Payroll/Views/Shared/_LayoutPayroll.cshtml";
}
app-assets
Static front-end assets live under DamsyERP.UI/app-assets/:
| Path | Contents |
|---|---|
css/shell-modern.css | Global shell styling |
css/sidebar-unified.css | Unified sidebar across modules |
css/payroll-modern.css, payroll-dashboard.css | Payroll-specific styling |
js/ | Shared JavaScript utilities |
Module views reference these via ~/app-assets/... paths. Keep module-specific CSS alongside generic shell styles rather than duplicating layout markup.
Web Forms report viewers
Crystal Reports use legacy Web Forms .aspx pages inside Areas (for example Areas/Payroll/PayRollViewerForm/PayRollReportsForm.aspx). MVC RouteConfig ignores Crystal image handler routes. See Crystal Reports.
Developer Notes
UserLoginvsIndex: Login GET is at/Login/Index;/Login/UserLoginredirects to Index for backward compatibility.- Shared employee screens: Root
EmployeeMControllerusesSession["Module"]to determine which module initiated the screen. - Partial views for AJAX: Many modules return
PartialVieworJsonResultfor DataTables and modal workflows. - Area-specific ManageError: Most Areas duplicate
ManageErrorControllerand views so error pages retain module chrome.
When adding a new Payroll screen, place the view under Areas/Payroll/Views/<Controller>/ and rely on _ViewStart.cshtml to apply _LayoutPayroll automatically.
Examples
Linking to a Payroll action from a view
<a href="@Url.Action("Index", "SalaryProcess", new { area = "Payroll" })">
Salary Process
</a>
Redirect from root to an Area
return RedirectToAction("Index", "PayrollDashboard", new { area = "Payroll" });
ModuleManagement entry (from dashboard tile)
/Login/ModuleManagement?PageID=Payroll
→ RedirectToAction("Index", "PayrollDashboard", new { area = "Payroll" })
Related Pages
Important Notes
Routes Adminisration and ManagmentDashBoard are baked into URLs, AreaRegistration classes, and redirects. Renaming folders without a coordinated migration breaks production links.
Sales and Operation modules may use shared or inline layout patterns. Check the specific controller's views for the active layout reference before assuming a _SalesLayout exists.
Common Mistakes
| Mistake | Result |
|---|---|
Creating a view under Views/ instead of Areas/<Area>/Views/ | View not found for Area controller |
Omitting area in Url.Action | Link resolves to root controller (404 or wrong screen) |
Skipping CompID session check | Unauthenticated access or null reference in DAL |
| Adding SPA-style client routing | Conflicts with server-rendered MVC pattern used throughout |
Next Steps
- Read Request Pipeline for routing and startup configuration.
- Read Module Routing for the full PageID → Area mapping table.