ASP.NET Core  

Integrating Angular Material with ASP.NET Core for a Modern UI

A Complete End-to-End Guide for Building Enterprise-Ready Apps

Introduction

Modern web applications are expected to be clean, fast, and visually appealing. Users expect smooth navigation, polished components, responsive layouts, and consistency across screens. For teams building enterprise applications with ASP.NET Core on the backend and Angular on the frontend, Angular Material is one of the most reliable ways to deliver a modern UI without having to design everything from scratch.

The combination of ASP.NET Core and Angular Material provides:

  • A scalable and secure backend

  • A refined, modern, consistent frontend

  • Faster development due to ready-made components

  • Support for responsive layouts and accessibility

  • A unified developer experience

This article is a complete guide to integrating Angular Material with an ASP.NET Core + Angular application. We will explain architecture, installation, configuration, UI development, theming, best practices, state management, and production deployment.

This guide is suited for beginner to senior developers.

Understanding the Project Structure

When you create an ASP.NET Core + Angular application using the built-in template:

dotnet new angular -o MyApp

You get the following structure:

MyApp/
 ├── Controllers/
 ├── ClientApp/  (Angular project)
 ├── wwwroot/
 ├── Program.cs
 ├── appsettings.json

Key points:

  • ASP.NET Core hosts the API and also serves compiled Angular files for production

  • Angular code lives inside ClientApp

  • Angular Material will be installed inside this ClientApp folder

Installing Angular Material

Move inside the Angular project:

cd ClientApp

Install Angular Material:

ng add @angular/material

This command:

  • Installs Angular Material and CDK

  • Sets up animations

  • Configures a default theme

  • Updates Angular configuration

Choose options like:

  • Theme: Indigo/Pink or an enterprise theme

  • Global typography styles: Yes

  • Browser animations: Yes

After this, the Angular project is ready for Material integration.

Setting Up Angular Material Modules

Angular Material is modular. Instead of importing the full library, you should import only required components to improve load time.

Create a dedicated Material module:

ClientApp/src/app/material.module.ts

import { NgModule } from '@angular/core';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatListModule } from '@angular/material/list';
import { MatInputModule } from '@angular/material/input';
import { MatCardModule } from '@angular/material/card';
import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';

@NgModule({
  exports: [
    MatToolbarModule,
    MatButtonModule,
    MatIconModule,
    MatSidenavModule,
    MatListModule,
    MatInputModule,
    MatCardModule,
    MatTableModule,
    MatPaginatorModule,
    MatSortModule
  ]
})
export class MaterialModule {}

Import this in app.module.ts:

import { MaterialModule } from './material.module';

@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
    MaterialModule
  ]
})
export class AppModule { }

This gives the Angular app a consistent UI foundation.

Creating a Material Layout (Toolbar + Sidenav)

Let us create a modern admin layout using Angular Material.

app.component.html

<mat-sidenav-container>

  <mat-sidenav #sidenav mode="side" opened>
    <mat-nav-list>
      <a mat-list-item routerLink="/dashboard">Dashboard</a>
      <a mat-list-item routerLink="/customers">Customers</a>
      <a mat-list-item routerLink="/reports">Reports</a>
    </mat-nav-list>
  </mat-sidenav>

  <mat-sidenav-content>
    <mat-toolbar color="primary">
      <button mat-icon-button (click)="sidenav.toggle()">
        <mat-icon>menu</mat-icon>
      </button>
      <span>My Enterprise App</span>
    </mat-toolbar>

    <div class="content">
      <router-outlet></router-outlet>
    </div>

  </mat-sidenav-content>

</mat-sidenav-container>

Add layout styling:

styles.css

mat-sidenav-container, mat-sidenav-content, mat-sidenav {
  height: 100%;
}

.content {
  padding: 20px;
}

This gives a standard dashboard layout similar to popular enterprise systems.

Connecting Angular Material UI with ASP.NET Core APIs

Angular Material gives UI components. ASP.NET Core provides APIs. Let us connect them.

Build a Customers API in ASP.NET Core

Controllers/CustomersController.cs

[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
    private static List<Customer> _data = new()
    {
        new Customer { Id = 1, Name = "Amit Patel", Email = "[email protected]" },
        new Customer { Id = 2, Name = "Priya Sharma", Email = "[email protected]" }
    };

    [HttpGet]
    public IActionResult GetAll()
    {
        return Ok(_data);
    }
}

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

Run API using:

dotnet run

Fetch Data in Angular

Create service:

ClientApp/src/app/services/customer.service.ts

@Injectable({ providedIn: 'root' })
export class CustomerService {

  private baseUrl = '/api/customers';

  constructor(private http: HttpClient) {}

  getCustomers(): Observable<Customer[]> {
    return this.http.get<Customer[]>(this.baseUrl);
  }
}

export interface Customer {
  id: number;
  name: string;
  email: string;
}

Displaying Data using Angular Material Table

Create customer listing component:

ng generate component customers

customers.component.html

<mat-card>
  <h2>Customer List</h2>

  <table mat-table [dataSource]="dataSource" matSort>

    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
      <td mat-cell *matCellDef="let customer">{{ customer.id }}</td>
    </ng-container>

    <ng-container matColumnDef="name">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
      <td mat-cell *matCellDef="let customer">{{ customer.name }}</td>
    </ng-container>

    <ng-container matColumnDef="email">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
      <td mat-cell *matCellDef="let customer">{{ customer.email }}</td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>

  </table>

  <mat-paginator [pageSize]="5"></mat-paginator>
</mat-card>

Component logic:

customers.component.ts

export class CustomersComponent implements OnInit {

  displayedColumns: string[] = ['id', 'name', 'email'];
  dataSource = new MatTableDataSource<Customer>();

  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  constructor(private service: CustomerService) {}

  ngOnInit() {
    this.service.getCustomers().subscribe(res => {
      this.dataSource.data = res;
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
    });
  }
}

The table provides sorting and pagination out of the box.

Building Forms with Angular Material

Example form:

customer-form.component.html

<mat-card>
  <mat-form-field appearance="fill">
    <mat-label>Name</mat-label>
    <input matInput [(ngModel)]="model.name">
  </mat-form-field>

  <mat-form-field appearance="fill">
    <mat-label>Email</mat-label>
    <input matInput [(ngModel)]="model.email">
  </mat-form-field>

  <button mat-raised-button color="primary">Save</button>
</mat-card>

Angular Material forms are responsive and accessible, ideal for data entry screens.

Themeing Angular Material for Enterprise Use

Angular Material comes with built-in themes but enterprises usually define brand colours.

styles.scss

@use '@angular/material' as mat;

$primary: mat.define-palette(mat.$indigo-palette);
$accent: mat.define-palette(mat.$deep-purple-palette);
$warn: mat.define-palette(mat.$red-palette);

$theme: mat.define-light-theme((
  color: (
    primary: $primary,
    accent: $accent,
    warn: $warn
  )
));

@include mat.all-components-theme($theme);

You can:

  • Add dark mode

  • Build multiple themes

  • Apply theme switching inside Angular

Enterprises often define two themes: corporate and high-contrast mode.

Authentication UI with Material

Using mat-form-field and mat-card you can build login pages.

Example:

<mat-card class="login-card">
  <h2>Login</h2>
  <mat-form-field appearance="fill">
    <mat-label>Email</mat-label>
    <input matInput>
  </mat-form-field>

  <mat-form-field appearance="fill">
    <mat-label>Password</mat-label>
    <input matInput type="password">
  </mat-form-field>

  <button mat-raised-button color="primary">Login</button>
</mat-card>

This can integrate with ASP.NET Core Identity or JWT-based auth.

Using Material Dialogs

Dialogs are common in enterprise software.

Example:

open-dialog method:

openDeleteDialog(customer: Customer) {
  const dialogRef = this.dialog.open(DeleteConfirmDialog, {
    data: customer
  });

  dialogRef.afterClosed().subscribe(result => {
    if (result === true) {
      this.delete(customer.id);
    }
  });
}

Dialog component:

@Component({
  selector: 'delete-confirm-dialog',
  template: `
  <h2 mat-dialog-title>Confirm Delete</h2>
  <mat-dialog-content>Are you sure?</mat-dialog-content>
  <mat-dialog-actions>
    <button mat-button [mat-dialog-close]="false">Cancel</button>
    <button mat-button color="warn" [mat-dialog-close]="true">Delete</button>
  </mat-dialog-actions>
  `
})
export class DeleteConfirmDialog {}

This provides a clean confirmation workflow.

Best Practices for ASP.NET Core + Angular Material Projects

Use Angular Lazy Loading

Divide modules:

  • DashboardModule

  • CustomerModule

  • ReportsModule

This improves performance.

Use Angular Material Responsively

Use:

  • fxLayout (Flex Layout)

  • mat-grid-list

Mobile experience matters for modern enterprise apps.

Use DTOs and Validation in ASP.NET Core

Never expose EF Core entities directly. Use:

  • Data Transfer Objects

  • Fluent Validation or DataAnnotations

Caching and Compression

Enable response compression in ASP.NET Core:

builder.Services.AddResponseCompression();
app.UseResponseCompression();

Pre-rendering or SSR

For SEO or fast first render, consider Angular Universal with ASP.NET Core.

Running in Production

Build Angular:

ng build --configuration production

Publish ASP.NET Core:

dotnet publish -c Release -o ./publish

Deploy to:

  • Azure App Service

  • AWS Elastic Beanstalk

  • IIS

  • Docker container

Make sure wwwroot contains Angular files.

Troubleshooting Tips

Angular not loading in production

Clear baseHref in angular.json or set correctly.

API unreachable

Ensure correct relative path:

private baseUrl = '/api/customers';

CORS issues

Enable in ASP.NET Core:

app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

Conclusion

Integrating Angular Material with ASP.NET Core gives you a powerful combination for building scalable, enterprise-grade applications with a professional and modern UI. Angular Material provides the UI components, responsive layout system, and themeing capabilities needed to deliver a polished experience. ASP.NET Core handles the API, business logic, security, and deployment.

With best practices like modular design, lazy loading, themeing, DTO-based APIs, and clean separation of concerns, this stack becomes suitable for both large corporations and startups building production software.

This architecture is used widely in:

  • ERP and CRM systems

  • Internal admin dashboards

  • Cloud SaaS platforms

  • Healthcare and banking apps

  • Enterprise reporting tools

Together, ASP.NET Core and Angular Material help teams build software that looks modern, performs well, and scales for years.