Angular & ASP.NET Web API – Uploading Image Binaries to a Database


In the example, images will be uploaded to a local MDF file table using Angular and ASP.NET C# Web API. This is the easiest solution to understanding how this works. A better example will be added in the coming months.

The Angular UI with Bootstrap will have a form and a table on the right side to display the images. When a new image is added the form will alert the parent component using the @Output() decorator to update the table component using the @ViewChild() decorator. The service uses a Promise instead of an observable for this example.

Not all of the code will be in the page below, so please get the Angular App and Web API from the Github repository You will have to update the Nuget packages for the API. The API was developed using VS2019. For the UI, please run npm install before ng serve.

Before you can run the API

Try running the following command in the Package Manager Console

use nuget locals all -clear 


dotnet nuget locals all --clear

Also may need to update the installed Nuget Packages.

Then Cloning this repo will require you to install the nuget packages. Try an update to get everything installed


First lets create a table in SSMS. You can run the script or use designer.

CREATE TABLE [dbo].[ProfileImages](
	[ImageId] [int] IDENTITY(1,1) NOT NULL,
	[Label] [varchar](40) NULL,
	[Description] [varchar](300) NULL,
	[Filename] [varchar](50) NULL,
	[Size] [int] NULL,
	[URL] [varchar](100) NULL,
	[MimeType] [varchar](30) NULL,
        [IsActive] [bit] NULL,
	[Image] [image] NULL,
	[Id] ASC


The form will have three fields. Fields for title, description, and file upload field. To make it a bit more interesting we will capture and display the image in separate area along with the file size, mime type, and file name.

Create a class for the file meta data.

class MediaImageClass {
  ImageId: number;
  Label: string;
  Description: string;
  Filename: number;
  UploadDate: any;
  Size: number;
  MimeType: string;
  Image: any;

Create a new instance of the class.

private imageFormData = new MediaImageClass();

Generate a service labeled image-file

ng g s services/image-file

Create two components. On for the form and another for the table

ng g c components/file-form
ng g c components/file-table

In the form Component, import the following:

import { Component, OnInit, OnDestroy, EventEmitter, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Subscription } from 'rxjs';
import { ImageFileService } from 'src/app/services/image-file.service';

Create a form as follows.

ngOnInit() {
    this.imageForm ={
      label: ['', [Validators.required]],
      description: [''],
      image: [null, [Validators.required]],

The onSubmit() function will simply call a Promise instead of an Observable. After calling the service, clear out the form and alert the parent that a new record has been added.

  onSubmit($event) {
    this.imageFormData.AutoId = '1';
    this.imageFormData.Title = this.automotiveForm.controls.title.value;
    this.imageFormData.Label = this.imageForm.controls.label.value;
    this.imageFormData.Description = this.imageForm.controls.description.value;



HTML Template

<form class="post-form" method="POST" (ngSubmit)="onSubmit($event)" [formGroup]="imageForm" >

          <div class="row">
            <div class="col-6">

          <div class="row">
            <div class="col-12">
                <input type="text" class="form-control" placeholder="Label" name="Label" formControlName="label">
          <div class="row mt-3">
            <div class="col-12">
              <textarea class="form-control"  formControlName="description"></textarea>

          <div class="row mt-3">
            <div class="col-6">
              <div class="custom-file-upload">
                <label for="file-upload" class="custom-file-upload1">
                  <i class="fa fa-cloud-upload"></i> Choose File
                <input #file  type="file" id="file-upload" accept='image/*' (change)="preview(file.files)" class="form-control"  formControlName="image">

          <div class="row mt-3">
            <div class="col">
                <button class="btn btn-primary" type="submit" [disabled]="!imageForm.valid">Save Image & Title</button>

The image preview section of the HTML template.

 <div class="row mu-5">
    <div class="col-md-6 text-center">
        <img mat-card-image [src]="imgURL"  alt="Photo" style="width: 90%; height: 90%" *ngIf="imgURL">
        <img mat-card-image [src]="imageURL"  alt="Photo" style="width: 90%; height: 90%"   <div class="row">
          <div class="col-4 text-left">
            <div *ngIf="Size !== 0">
              File Name: {{Filename}}<br><br>
              Size: {{Size}}<br><br>
              Format: {{MimeType}}<br><br>
          <div class="col-5 text-left">
            <img mat-card-image [src]="imgURL"  alt="Photo" style="height: auto; width: 250px; object-fit: cover;" *ngIf="imgURL">
            <img mat-card-image [src]="imageURL"  alt="Photo" style="height: auto; width: 250px; object-fit: cover;" *ngIf="!imgURL">

Note: Currently working on calling this as an Observable.

  addImageToDB(fileForm: any): string {
    const URL = `${environment.baseUrl}/api/userimage/addtodb`;

    const formData = new FormData();
    // Add the file
    formData.append(, fileForm.Image);
    // Add file Label and Description
    formData.append('Label', fileForm.Label);
    formData.append('Description', fileForm.Description);
    let status = '';

    // Use a promise for this example
    const promise = new Promise((resolve, reject) => {, formData)
          res => { // Success
            status = 'resolved';
        .catch((err) => {
          status = 'rejected';
    return status;


From your ASP.NET Web API Controller please add a method with the route addimageToDB

For attribute routing for the class.

public class UserImageController : ApiController

Create a Post Method to record the image.

IMPORTANT: The folder must exist on the server your API is deployed to. In this example APP_DATA is used but it will not exist on the server. You can use “~/Content” instead or add a folder to the app after it’s deployed. Make sure the folder has read write access.

// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
    throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);

var ctx = HttpContext.Current;
var root = ctx.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);        

Getting the image specs with MultipartFileData before saving to the database.

await Request.Content.ReadAsMultipartAsync(provider);
var uniqueFileName = "";
NameValueCollection formdata = provider.FormData;

UserImage imageForm = new UserImage();
imageForm.IsActive = true;
imageForm.Label = formdata["Label"];
imageForm.Description = formdata["Description"];
imageForm.DateCreated = today;

// You can get the file specification from ASP.NET C#

foreach (MultipartFileData file in provider.FileData)
    var fileName = file.Headers.ContentDisposition.FileName.Replace("\"", string.Empty);
    string mimeType = file.Headers.ContentType.MediaType;

    byte[] documentData = File.ReadAllBytes(file.LocalFileName);

    imageForm.ImageData = documentData;
    imageForm.MimeType = mimeType;
    imageForm.Size = documentData.Length;