Project Overview

Tech Stack:

Features

  1. Upload an image from Angular UI

  2. Save the image in SQL Server (varbinary(max))

  3. Retrieve and display the image

Step 1: SQL Server Database Setup

Create a table to store images:

Code
CREATE TABLE EmployeeImages (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    FileName NVARCHAR(255),
    ContentType NVARCHAR(100),
    Data VARBINARY(MAX)
);

Step 2: ASP.NET Core API Setup

2.1 Create ASP.NET Core Web API Project

Code
dotnet new webapi -n ImageUploadApi
cd ImageUploadApi

2.2 Create the Model

Models/EmployeeImage.cs:

Code
namespace ImageUploadApi.Models
{
    public class EmployeeImage
    {
        public int Id { get; set; }
        public string FileName { get; set; }
        public string ContentType { get; set; }
        public byte[] Data { get; set; }
    }
}

2.3 Create DbContext

Data/AppDbContext.cs:

Code
using ImageUploadApi.Models;
using Microsoft.EntityFrameworkCore;

namespace ImageUploadApi.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

        public DbSet<EmployeeImage> EmployeeImages { get; set; }
    }
}

Add connection string in appsettings.json:

Code
"ConnectionStrings": {
  "DefaultConnection": "Server=YOUR_SERVER;Database=ImageDb;Trusted_Connection=True;TrustServerCertificate=True;"
}

Register DbContext in Program.cs:

Code
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

2.4 Create Controller for Image Upload

Controllers/ImagesController.cs:

Code
using ImageUploadApi.Data;
using ImageUploadApi.Models;
using Microsoft.AspNetCore.Mvc;

namespace ImageUploadApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ImagesController : ControllerBase
    {
        private readonly AppDbContext _context;

        public ImagesController(AppDbContext context)
        {
            _context = context;
        }

        [HttpPost("upload")]
        public async Task<IActionResult> Upload([FromForm] IFormFile file)
        {
            if(file == null || file.Length == 0)
                return BadRequest("No file selected.");

            using var ms = new MemoryStream();
            await file.CopyToAsync(ms);

            var image = new EmployeeImage
            {
                FileName = file.FileName,
                ContentType = file.ContentType,
                Data = ms.ToArray()
            };

            _context.EmployeeImages.Add(image);
            await _context.SaveChangesAsync();

            return Ok(new { image.Id });
        }

        [HttpGet("{id}")]
        public async Task<IActionResult> GetImage(int id)
        {
            var image = await _context.EmployeeImages.FindAsync(id);
            if(image == null) return NotFound();

            return File(image.Data, image.ContentType);
        }

        [HttpGet]
        public async Task<IActionResult> GetAll()
        {
            var images = await _context.EmployeeImages.Select(i => new {
                i.Id,
                i.FileName
            }).ToListAsync();

            return Ok(images);
        }
    }
}

Step 3: Angular Frontend

3.1 Install HttpClientModule

In app.module.ts:

Code
import { HttpClientModule } from '@angular/common/http';

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

3.2 Create Image Service

services/image.service.ts:

Code
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

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

  apiUrl = 'https://localhost:5001/api/images';

  constructor(private http: HttpClient) {}

  uploadImage(file: File): Observable<any> {
    const formData = new FormData();
    formData.append('file', file);
    return this.http.post(`${this.apiUrl}/upload`, formData);
  }

  getImage(id: number): Observable<Blob> {
    return this.http.get(`${this.apiUrl}/${id}`, { responseType: 'blob' });
  }

  getAllImages(): Observable<any[]> {
    return this.http.get<any[]>(this.apiUrl);
  }
}

3.3 Create Upload Component

image-upload.component.ts:

Code
import { Component } from '@angular/core';
import { ImageService } from '../services/image.service';

@Component({
  selector: 'app-image-upload',
  templateUrl: './image-upload.component.html'
})
export class ImageUploadComponent {
  selectedFile: File | null = null;
  uploadedImages: any[] = [];

  constructor(private imageService: ImageService) {}

  onFileSelected(event: any) {
    this.selectedFile = event.target.files[0];
  }

  upload() {
    if(!this.selectedFile) return;

    this.imageService.uploadImage(this.selectedFile).subscribe(res => {
      alert('Upload Successful! ID: ' + res.id);
      this.loadImages();
    });
  }

  loadImages() {
    this.imageService.getAllImages().subscribe(images => {
      this.uploadedImages = images;
    });
  }

  viewImage(id: number) {
    this.imageService.getImage(id).subscribe(blob => {
      const url = URL.createObjectURL(blob);
      window.open(url);
    });
  }

  ngOnInit() {
    this.loadImages();
  }
}

3.4 Upload Component HTML

image-upload.component.html:

Code
<h3>Upload Image</h3>

<input type="file" (change)="onFileSelected($event)">
<button (click)="upload()">Upload</button>

<h4>Uploaded Images</h4>
<ul>
  <li *ngFor="let img of uploadedImages">
    {{ img.fileName }}
    <button (click)="viewImage(img.id)">View</button>
  </li>
</ul>

Step 4: Run the Project

  1. Run the ASP.NET Core API:

Code
dotnet run
  1. Run Angular app:

Code
ng serve
  1. Open Angular app at http://localhost:4200

Best Practices

  1. For large images, consider storing them on file system or cloud (Azure Blob, AWS S3) instead of SQL Server.

  2. Validate file type and size before uploading.

  3. Use async pipes or observables for efficient image loading.

  4. For production, enable CORS in ASP.NET Core for Angular:

Code
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAngular", policy =>
    {
        policy.WithOrigins("http://localhost:4200")
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});
Code
app.UseCors("AllowAngular");