Project Overview
Tech Stack:
Features
Upload an image from Angular UI
Save the image in SQL Server (varbinary(max))
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
Run the ASP.NET Core API:
dotnet run
Run Angular app:
ng serve
Open Angular app at http://localhost:4200
Select an image
Click upload
View the uploaded image
Best Practices
For large images, consider storing them on file system or cloud (Azure Blob, AWS S3) instead of SQL Server.
Validate file type and size before uploading.
Use async pipes or observables for efficient image loading.
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");