ASP.NET Core  

Upload Images From Angular and Store in SQL Server Using ASP.NET Core

Project Overview

Tech Stack:

  • Frontend: Angular

  • Backend: ASP.NET Core Web API

  • Database: SQL Server

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:

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

dotnet new webapi -n ImageUploadApi
cd ImageUploadApi

2.2 Create the Model

Models/EmployeeImage.cs:

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:

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:

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

Register DbContext in Program.cs:

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

2.4 Create Controller for Image Upload

Controllers/ImagesController.cs:

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:

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

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

3.2 Create Image Service

services/image.service.ts:

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:

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:

<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:

dotnet run
  1. Run Angular app:

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

  • Select an image

  • Click upload

  • View the uploaded image

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:

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