How to send Email in ASP.NET Core-Beginner’s Guide

How to send Email in ASP.NET Core-Beginner’s Guide

This article explain how to send Email in ASP.NET Core using MailKit.  For this article we consider ASP.NET Core 5.0, at the end of this article you will have full depth idea about how we can easily integrate Email in ASP.NET Core. Also please follow our article about how to send SMS using ASP.NET Core.

Find Source code in GitHub- ASP.NET Core 5.0
Find Source Code in GitHub- ASP.NET Core 3.1

Now-a-days application will send emails in plain text, support attachments (multiple attachments at once) and also we will learn how to Send Branded Emails using HTML Templates. Note that we will be using Mailkit to send the emails. This is what Microsoft recommends over the standard SMTPClient class.

What is MailKit ?

MailKit is an open-source cross-platform library that can be used in .NET or .NET Core applications running on Windows, Linux, or Mac. MailKit is a more like email clients of SMTP server. The SMTP server will have an address that will be used by email clients to send emails in ASP.NET Core. Based on the SMTP email server being used to send mails you will have to obtain server details like Host, Port, etc., and configure the same in your application.

What is SMTP Server ?

SMTP(Simple Mail Transfer Protocol) server are email based application servers that allow you to send and receive mails between senders & receivers. For e.g. Gmail is an SMTP server. On registering for email service these servers provided email id account using which we can send/receive emails on that SMTP Server.

What are going to discuss in this Post ?

In this post we are going to create examples of

  1. Send Email with Attachments
  2. Send Email With Custom Template

Creating ASP.NET Core Project and Implement Email Configuration

Let’s create a .NET Core Web API project considering ASO.NET Core 5.0 with selecting ASP.NET Core Web API.

Tick on Enable OpenAPI Support that enables SWAGGER into .NET Core API Project.

What is Swagger ?

Swagger is an Interface Description Language for describing RESTful APIs expressed using JSON. Swagger is used together with a set of open-source software tools to design, build, document, and use RESTful web services. Swagger includes automated documentation, code generation, and test-case generation

Add MailKit Nuget package to ASP.NET Core Project

Add SMTP Server & Email Account details in appsettings.json file

To send an email we need SMTP server which will connect to server to send emails. Also to access this SMTP server we will need security credentials to access that server i.e. details of the Email Account which has been created on that server to send emails will be required. Now, these details should not be hardcoded in code as these are configurable parameters that can change over time so we will store the above details in the appsettings.json file.

User Id & Password of the SMTP Server is very sensitive data and should not be stored in plain text in the appsettings.json file as it can be viewed by any person who has access to code or deployment environments. Instead, it should be securely stored somewhere so that it can be accessed only by unauthorized persons.

For demonstration purposes password is being stored in the appsettings.json file.

"EmailSettings": {
    "EMail": "corespiderpro@gmail.com",
    "Name": "CoreSpider-The Knowledge Hub",
    "Password": "**********",
    "Host": "smtp.gmail.com",
    "Port": 587
  }

As you see we use Gmail ID as SMTP server. For security I have made *** as Password, you can set your original Gmail password to set Gmail as SMTP ready.

Quick Tip to Secure Sensitive Data

During Development, It is advisable to add data that is to be kept private on to the appsettings.Development.Json. This file is generated while setting the Environment Variable to Development. While adding the project to source control, you can exclude the appsettings.Development.json, so that GIT ignores the file and does not commit it to the main repository. In this way, we can have a good separation of confidential information from the outside world.

Configure Gmail SMTP Server

To configure Gmail SMTP follow these steps.

Developers usually prefer using the GMAIL SMTP server for production and testing purposes, as it is quite easy and reliable too. Gmail allows you to send 2,000 emails per day using the Gmail SMTP Server for FREE. That’s pretty much to get started, right?

Here is what you will need to use Gmail SMTP.

  • Regarding Gmail ID (Do not use a personal Email ID, quite risky if compromised.)
  • The Password.
  • Host or SMTP Server address – If you are going with Gmail, use smtp.gmail.com
  • Port – Use 465 (SSL) or 587 (TLS)

After you get the details, we will need to allow your Gmail account to send emails using external (less- secure applications). To enable this, go to https://myaccount.google.com/security and turn ON Less Secure App Access.

Access the Appsettings.json file

To access the appsettings.json file we need to create a Settings folder inside our ASP.NET Core Web API project. And create a class with name as EmailSettings.

 public class EmailSettings
    {
        public string EMail { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
        public string Host { get; set; }
        public int Port { get; set; }
    }

We have the data in appsettings.json file. How do we transfer these data to an instance of EmailSettingsat runtime ? IOptions and Dependency Injection to the rescue. Navigate to Starup/ConfigureServices Method and add the following line.

services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));

Declaring the Model that hold Email Information’s

Let’s create a Model class holds the Email Information that responsible to send email with attachments. Create another model class that hold the information of Email and UserName that is responsible with templates.

  public class EmailInfo
    {
        public string EmailTo { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }
        public List<IFormFile> Attachments { get; set; }
    }
  public class EmailSource
    {
        public string EmailTo { get; set; }
        public string UserName { get; set; }
    }

Create a Interface that responsible to Send Email

Let’s create a Interface inside Services folder with declaring two methods.

public interface IEmailService
    {
        Task SendEmailAsync(EmailInfo emailInfo);
        Task SendEmailTemplateAsync(EmailSource emailSource);
    }

Create a Concrete class that implement Interface

We will have a method that takes in the EmailInfo object and sends the email. Next, Add a concrete class that will implement this interface. Services/EmailService.cs

 public class EmailService : IEmailService
    {
        private readonly EmailSettings _mailSettings;
        public EmailService(IOptions<EmailSettings> mailSettings)
        {
            _mailSettings = mailSettings.Value;
        }
        public async Task SendEmailAsync(EmailInfo emailInfo)
        {
            var email = new MimeMessage();
            email.Sender = MailboxAddress.Parse(_mailSettings.EMail);
            email.To.Add(MailboxAddress.Parse(emailInfo.EmailTo));
            email.Subject = emailInfo.Subject;
            var builder = new BodyBuilder();
            if (emailInfo.Attachments != null)
            {
                byte[] fileBytes;
                foreach (var file in emailInfo.Attachments)
                {
                    if (file.Length > 0)
                    {
                        using (var ms = new MemoryStream())
                        {
                            file.CopyTo(ms);
                            fileBytes = ms.ToArray();
                        }
                        builder.Attachments.Add(file.FileName, fileBytes, ContentType.Parse(file.ContentType));
                    }
                }
            }
            builder.HtmlBody = emailInfo.Body;
            email.Body = builder.ToMessageBody();
            using var smtp = new SmtpClient();
            smtp.Connect(_mailSettings.Host, _mailSettings.Port, SecureSocketOptions.StartTls);
            smtp.Authenticate(_mailSettings.EMail, _mailSettings.Password);
            await smtp.SendAsync(email);
            smtp.Disconnect(true);
        }

        public async Task SendEmailTemplateAsync(EmailSource emailSource)
        {
            string FilePath = Directory.GetCurrentDirectory() + "\\Templates\\CustomTemplate.html";
            StreamReader str = new StreamReader(FilePath);
            string MailText = str.ReadToEnd();
            str.Close();
            MailText = MailText.Replace("[username]", emailSource.UserName).Replace("[email]", emailSource.EmailTo);
            var email = new MimeMessage();
            email.Sender = MailboxAddress.Parse(_mailSettings.EMail);
            email.To.Add(MailboxAddress.Parse(emailSource.EmailTo));
            email.Subject = $"Welcome {emailSource.UserName}";
            var builder = new BodyBuilder();
            builder.HtmlBody = MailText;
            email.Body = builder.ToMessageBody();
            using var smtp = new SmtpClient();
            smtp.Connect(_mailSettings.Host, _mailSettings.Port, SecureSocketOptions.StartTls);
            smtp.Authenticate(_mailSettings.EMail, _mailSettings.Password);
            await smtp.SendAsync(email);
            smtp.Disconnect(true);
        }

    }

Code Explanation

Here we Injecting the IOptions<EmailSettings> to the constructor and assigning it’s value to the instance of EmailSettings. Like this, we will be able to access the data from the JSON at runtime.

SendEmailAsync

  • The basic idea is to create an object of MimeMessage (a class from Mimekit ) and send it using a SMTPClient instance (Mailkit).
  • Here we create new object of MimeMessage and adds in the Sender, To Address and Subject to this object. We will be filling the message related data (subject, body) from the mailRequest and the data we get from our JSON File.
  • If there are any attachments (files) in the request object, we transform the file to an attachment and add it to the mail message as an Attachment Object of Body Builder.
  • Send the Message using the SMTP SendMailAsync Method.

SendEmailTemplateAsync

  • We get the file path of our welcome template and read the file as a string. ( We create a HTML template name as CustomTemplate.html) inside “\Templates\CustomTemplate.html”.
  • Now, We replace the username and email tag with the actual data and here we adds a default subject
  • Set the body of the email from the template string and send email using SMTP SendAsync.

Add the Dependency Injection Service in startup.cs

services.AddTransient<IEmailService, EmailService>();

Create controller to send the Email

Let’s create a controller name as EmailController and here we call the service class.

 [Route("api/[controller]")]
    [ApiController]
    public class EmailController : ControllerBase
    {
        private readonly IEmailService mailService;
        public EmailController(IEmailService mailService)
        {
            this.mailService = mailService;
        }
        [HttpPost("sendEmail")]
        public async Task<IActionResult> SendMail([FromForm] EmailInfo emailInfo)
        {
            try
            {
                await mailService.SendEmailAsync(emailInfo);
                return Ok();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        [HttpPost("sendEmailTemplate")]
        public async Task<IActionResult> SendWelcomeMail([FromForm] EmailSource source)
        {
            try
            {
                await mailService.SendEmailTemplateAsync(source);
                return Ok();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }

Code Explanation

  • We make constructor Injection inside EmailController.
  • And we make [HttpPost(“sendEmail”)] that responsible to send email with attachments.
  • And we make [HttpPost(“sendEmailTemplate”)] that responsible to send email with templates.

Now we are ready ! All the configurations has been done and now we ready to test the Email using Swagger API.

Send Email – (Testing With Swagger)

Let’s build the application and run the project and as SWAGGER is already is configured while we create the project and select the Enable Open API Support.

Test Email with Attachment

To use email with attachment, add the email Id where we are going to sent email with Subject and Body. Here we added 3 attachments and then click on Execute button to send the email.

Let’s open the Gmail account and we can clearly seen that the Gmail SMTP work perfectly.

Test Email with Custom Template

We already create a custom HTML file inside Templates folder. Let’s using swagger we can test the email with templates file considering Email and UserName.

Let’s check the Gmail and we can see the Email with template

Source Code

Find Source code in GitHub- ASP.NET Core 5.0
Find Source Code in GitHub- ASP.NET Core 3.1

Summary

In this article, We covered all that is needed to Send Emails with ASP.NET Core. You can find source code in ASP.NET Core 5.0 and 3.1. Share your comments and suggestions about this article in the comments section below.

Have you enjoyed this post and found it useful? If so, please consider supporting me:

Buy me a coffeeBuy me a coffee

Latest Post

ASP.NET Core Web API with MongoDB CRUD- Beginner’s Guide
ASP.NET CORE WEB API 5.0 MONGODB CRUD

This article explain CRUD operation using MongoDB in ASP.NET Core Web API. We discuss here basics of MongoDB and how Read more

CRUD Operation in ASP.NET Web API with Entity Framework
CRUD-Operation-in-asp.net-Web-api

This blog explain CRUD Operation in ASP.NET Web API with Entity framework and then the web API check using POSTMAN Read more

Toast Notifications in ASP.NET Core Razor Pages
Toast Notifications in ASP.NET Core Razor Pages

This article we will learn how simply we can use Toast Notifications in ASP.NET Core Razor Pages 5.0. Mainly on Read more

Build CRUD REST APIs with ASP.NET Core 5.0 with EF Core 5.0
Build CRUD REST APIs with ASP.NET Core 5.0

This article explains how to build CRUD REST APIs with ASP.NET Core 5.0 with EF core 5.0 and API secured Read more

Angular 10 with ASP.NET Web API-CRUD Operations

Angular 10 with ASP.NET Web API-CRUD Operations

In this article we discuss create a CRUD application using Angular 10 with ASP.NET Web API. CRUD Operations (Insert Update and Delete) will be implemented inside an Asp .NET Web API Using Entity Framework and then consumed from an Angular 10 Application. Also please follow our previous blog post CRUD Operation in ASP.NET Web API with Entity Framework.

Find the Source code on the link

Prerequisite to start

Angular 10 & CLI
– ngx-Toastr (NPM package) & Bootstrap and Font-Awesome Icons
– Visual Studio Code & Visual Studio
– ASP .NET Web API & SQL Server
– Entity Framework

Create ASP.NET Web API Project

Let’s create a ASP.NET Web API Project to connect Angular application. Follow below steps to create ASP.NET Web API project. Open Visual studio choose ASP.NET Web Application and then select Empty template with checked Web API Project.

Create the Model Class

Let’s create a model of customer object. Right click on the Models folder and add the class named as Customer with following properties.

namespace CustomerAPI.Models
{
    [Table("Customer")]
    public class Customer
    {
        [Key]
        public int CustId { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string Mobile { get; set; }
        public string Email { get; set; }
    }
}
  • Here we create the Customer Model with above properties.
  • [Table(“Customer”)] is belong to System.ComponentModel.DataAnnotations.Schema namespace. Here Customer is the table name that we want to create dynamically using EF code first.
  • CustId is the primary key of our entity table so we added as [Key]

After creating the Models class must rebuild the applications. To rebuild the project right click on Project and then click Rebuild.

Adding the API Controller

To do database operations to create, update,read and delete over model class we need to create the controller that should do the CRUD operations for us. To create the Controller right click on the Controllers folder and add a new Controller and in the prompt choose as Web API2 controller with actions, using Entity framework like below. Here we can use in-built entity framework scaffold technique to create CRUD query for us.

After click the Add button a prompt will open to scaffold the model to create CRUD operations and choose Web API2 controller with actions, using Entity Framework.

  • In the Model Class choose the Model, in our case it is customer model class.
  • In the Data Context class, add + symbol and add the CustomerAPI Context.
  • Controller name in our case is CustomerController

After create the scaffold controller automatically it create the CRUD ( Create, Read, Update, Delete ) operations using Customer Model class and CustomerAPI Context class like below.

public class CustomersController : ApiController
    {
        private CustomerAPIContext db = new CustomerAPIContext();

        // GET: api/Customers
        public IQueryable<Customer> GetCustomers()
        {
            return db.Customers;
        }

        // GET: api/Customers/5
        [ResponseType(typeof(Customer))]
        public IHttpActionResult GetCustomer(int id)
        {
            Customer customer = db.Customers.Find(id);
            if (customer == null)
            {
                return NotFound();
            }

            return Ok(customer);
        }

        // PUT: api/Customers/5
        [ResponseType(typeof(void))]
        public IHttpActionResult PutCustomer(int id, Customer customer)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != customer.CustId)
            {
                return BadRequest();
            }

            db.Entry(customer).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!CustomerExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

        // POST: api/Customers
        [ResponseType(typeof(Customer))]
        public IHttpActionResult PostCustomer(Customer customer)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.Customers.Add(customer);
            db.SaveChanges();

            return CreatedAtRoute("DefaultApi", 
                                   new { id = customer.CustId }, customer);
        }

        // DELETE: api/Customers/5
        [ResponseType(typeof(Customer))]
        public IHttpActionResult DeleteCustomer(int id)
        {
            Customer customer = db.Customers.Find(id);
            if (customer == null)
            {
                return NotFound();
            }

            db.Customers.Remove(customer);
            db.SaveChanges();

            return Ok(customer);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool CustomerExists(int id)
        {
            return db.Customers.Count(e => e.CustId == id) > 0;
        }
    }
API Context Class

After adding the scaffold controller the API context class is also created inside the Model folder like below, that should contains the context of database schema. Here you can see CustomerAPIContext class implement the DbContext and base(“name=CustomerAPIContext”) is the name of the connection string to communicate with DB.

public class CustomerAPIContext : DbContext
    {
        public CustomerAPIContext() : base("name=CustomerAPIContext")
        {
        }
        public System.Data.Entity.DbSet<CustomerAPI.Models.Customer> 
                       Customers { get; set; }
    }

Entity Framework Code First Migrations

Code first migrations here help you to update the existing database with your newly added model classes and your existing database remains intact with the existing data.

  • Open Package manager console of the API project and type the command Enable-Migrations and hit enter.

After adding this command a Migrations folder is generated like blow with crating the Configuration.cs class. This class is derived from DbMigrationsConfiguration class. This class contains a Seed method having the parameter as the context class that we got generated in the Models Seed is an overridden method that means it contains a virtual method in a base class and a class driven from DbMigrationsConfiguration can override that and add custom functionality.

internal sealed class Configuration : DbMigrationsConfiguration<CustomerAPI.Models.CustomerAPIContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }
    }
The next step is to execute the command named “Add-Migrations”. In the package manager console. The command would be Add-Migrations Initial “Initial” is the parameter we have use, you may be use any other text as per your choice.

After executing the command it adds a new file with the name “Initial” prefixed with the date time stamp. It prefixes the date time stamp so that it could track the various migrations added during development and segregate between those. Open the file and we see the class named “Initial” deriving from DbMigration class. This class contains two methods that are overridden from DbMigration class i.e. the base class. The method names are Up() and Down().

The Up method is executed to add all the initial configuration to the database and contains the create command in LINQ format. This helps to generate tables and all the modifications done over the model. Down command is the opposite of Up command. The code in the file is self-explanatory. The Up command here is having the code that creates the Students table and setting Id as its primary key. All this information is derived from the model and its changes.

  • The final command that creates the database and respective tables out of our context and model. It executes the Initial migration that we added and then runs the seed method from the configuration class. This command is smart enough to detect which migrations to run. For example it will not run previously executed migrations and all the newly added migrations each time will be taken in to account to be executed to update the database. It maintains this track as the database firstly created contains an additional table named __MigrationHistory that keeps track of all the migrations done.
  • The command is Update-Database
  • After the command execution, it creates the database in the specified server as per your server and adds the corresponding connection string to the Web.Config file. The name of the connection string is the same as the name of our context class and that’s how the context class and connection strings are related.
<connectionStrings>
    <add name="CustomerAPIContext" connectionString="Data Source=ServerName; Initial Catalog=customers; User ID=sa;password=*****;"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

Now it automatically create the database named as “customers” with table name “customer”. Also it holds the migration history in the tables.

Exploring the Generated Database

You can see when navigate to SQL Server, find their the database is created for us.

But there is may be issue to access the Web API due to CORS. Let’s understand CORS

What is CORS and how & why to enable CORS in ASP.NET Web API ?

CORS (Cross-Origin Resource Sharing) : cross-origin HTTP request occurs when it requests a resource from a different domain, protocol, or port than the one from which the current document originated.

In this application, our web API project will block request from angular application, since they are cross-origin HTTP request(from different port numbers – 4200 and 49243). In-order to allow cross-origin HTTP request, we have to configure Web API project for this localhost:4200 request. so let’s look how we can do that.

How to enable CORS in ASP.NET Web API Project
  • To enable CORS in ASP.NET Web API Project add the below package in ASP.NET Web API application. To add this package you can select the project then on Nuget package search CORS and install this.

Also you can install this package using Nuget package manager console using below command

Install-Package Microsoft.AspNet.WebApi.Cors -Version 5.2.3
  • Then to enable the CORS add the below code inside WebApiConfig.cs file, present in App_start folder.
public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();
            var cors = new EnableCorsAttribute("*", "*", "*");
            //origins,headers,methods   
            config.EnableCors(cors);
        }
    }

Now the ASP.NET Web API project project is complete, let’s create an Angular 10 application and consume the Web API inside the angular application.

Create Angular 10 Application

To create angular application we use Visual studio code editor. You can choose any editor using Angular CLI.

Creating new angular application

To create the Angular application with name NgCustomerCRUD and install default packages from npm, you can use following command.

ng new NgCustomerCRUD

Add Required Angular CRUD Components

Add the below CRUD Components using below command.

# from root component
   ng g c customers
# switch to parent component directory
   cd src\app\customers
# create child components
   ng g c customer
   ng g c customer-list

we creates customers component, remaining two components will be child components for this customers component. following command creates child components customer and customer-list components.

Open appmodule.ts file, Make sure that newly added components are added to declarations array.

import { CustomersComponent } from './customers/customers.component';
import { CustomerComponent } from './customers/customer/customer.component';
import { CustomerListComponent } from './customers/customer-list/customer-list.component';
import { ToastrModule } from 'ngx-toastr';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
  declarations: [
    AppComponent,
    CustomersComponent,
    CustomerComponent,
    CustomerListComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule,
    BrowserAnimationsModule,
    ToastrModule.forRoot()
  ],

Angular 10 Project Structure

The below are the project structure of Angular application of the Customer CRUD application. On the below we use

On the src/app folder we create the root component name as “Customers” along with html and css files.
Then add the customer form component inside the Customers folder.
Then add the customer-list component to view the customer data and in their we should create the Edit & Delete.
Under the shared folder we add the service class name as “customer.service.ts” to call the Web API and a model class is create name as “customer.model.ts” that hold the customer object.
And, finally add all the components info into the app.model.ts file and add the CDN file for style or you can install these file manually and add it into angular.json file.

● src
+---● app
|   +--● customers (the root component)
|   |  |--customers.component.ts|.html|.css
|   |  +--● customer (customer form)
|   |  |  |--customer.component.ts|.html|.css
|   |  |
|   |  +--● customer-list (list inserted customers)
|   |  |  |--customer-list.component.ts|.html|.css
|   |  |
|   |  +--● shared
|   |     |--customer.service.ts
|   |     |--customer.model.ts
|   |
|   |--app.module.ts
|
+---● environments
|   |--environment.ts
|
|--index.html (cdn path for bootstrap and font awesome icon)

Create Service and Model Class

To create these classes let’s add a new folder sharedinside customers folder (/src/app/customers/ ).

Now create customer model class

# switch to shared folder
cd src\app\customers\shared
# create customer model class
ng g class customer --type=model
# create customer service class
ng g s customer

Let’s create the customer model class with following properties. CustId is the property that hold each record individually.

export class Customer {
    CustId:number;
    Name:string;
    Address:string;
    Mobile:string;
    Email:string;
}

Create Service Class to consume ASP.NET Web API, the service name is customer.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of, Subject } from 'rxjs';
import { Customer } from './customer.model';
const baseURL = 'http://localhost:49243/api/Customers';
@Injectable({
  providedIn: 'root'
})
export class CustomerService {
  selectedCustomer : Customer;
  CustomerList : Observable<Customer[]>;

  constructor(private httpClient: HttpClient) {
   }
  getCustomerList(): Observable<Customer[]> {  
    this.CustomerList=this.httpClient.get<Customer[]>(baseURL);  
    return this.CustomerList;  
  }  
  getCustomerById(id): Observable<any> {
    return this.httpClient.get(`${baseURL}/${id}`);
  }
  addCustomer(data): Observable<any> {
    return this.httpClient.post(baseURL, data);
  }
  updateCustomer(id, data): Observable<any> {
    return this.httpClient.put(`${baseURL}/${id}`, data);
  }
  deleteCustomer(id): Observable<any> {
    return this.httpClient.delete(`${baseURL}/${id}`);
  }
  deleteAllCustomer(): Observable<any> {
    return this.httpClient.delete(baseURL);
  }
  searchByCustomer(name): Observable<any> {
    return this.httpClient.get(`${baseURL}?name=${name}`);
  }
}
  • In this service class we have imported http and rxjs related classes. http class is used to consume the Web API methods for Insert Update and Delete operations.
  • The model class customer.model.ts is inject into service class.
  • baseURL = ‘http://localhost:49243/api/Customers’ is the URL of ASP.NET Web API to consume the service.
  • selectedCustomer is the variable that hold the customer model class.
  • CustomerList is contains the Observable<Customer[]>.
  • getCustomerList to fetch all the customer information and getCustomerById(id) fetch the customer information by Id.
  • addCustomer and updateCustomer method service use for customer information add and update the data.
  • deleteCustomer and searchByCustomer accordingly use to do the CRUD operation.

Design the CRUD Customer Template

We use bootstrap and font-Awesome Icons For Application Design. So first of all add CDN reference for these style sheets inside index.html. You can also add the package and use it.
  <!-- Bootstrap -->
<link rel="preload" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" data-rocket-async="style" as="style" onload="this.onload=null;this.rel='stylesheet'" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<!-- font-awesome -->
<link rel="preload" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" data-rocket-async="style" as="style" onload="this.onload=null;this.rel='stylesheet'">
Update add the selector <app-customers> app.component.html as follows

<div class="container">
  <app-customers></app-customers>
</div>
Add the following selector inside the customers.component.html file.

<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <a class="navbar-brand" href="#">Customer Angular CRUD using ASP.NET Web API</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" 
         data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" 
                    aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
  </nav>
  <div class="row mt-2">
    <div class="col-md-6">
      <app-customer></app-customer>
    </div>
    <div class="col-md-6">
      <app-customer-list></app-customer-list>
    </div>
  </div>

Angular CRUD Operations Form

we’ll create a customer form to implement Insert and Update Operation with customer Component. So we are going to create a Template Driven Form(TDF) using selectedCustomer property from injected CustomerService Class.

Insert Update  and Reset Operation

Let’s discuss how to add the customer component with TS file and html.

customer.component.html

<form class="cust-form" #customerForm="ngForm" (ngSubmit)="onSubmit(customerForm)">
    <input type="hidden" name="CustId" #CustId="ngModel" [(ngModel)]="custservice.selectedCustomer.CustId">
   
      <div class="form-group  col-md-8">
        <input class="form-control" name="Name" #Name="ngModel" [(ngModel)]="custservice.selectedCustomer.Name"
          placeholder=" Name" required>
        <div class="validation-error" *ngIf="Name.invalid && Name.touched" style="color: red;">This Field is Required.</div>
      </div>
    
    <div class="form-group col-md-8">
      <input class="form-control" name="Address" #Address="ngModel" [(ngModel)]="custservice.selectedCustomer.Address" placeholder="Address"
        required>
      <div class="validation-error" *ngIf="Address.invalid && Address.touched" style="color: red;">This Field is Required.</div>
    </div>

    <div class="form-group col-md-8">
      <input class="form-control" name="Mobile" #Mobile="ngModel" [(ngModel)]="custservice.selectedCustomer.Mobile" 
         placeholder="Mobile" required>
      <div class="validation-error" *ngIf="Mobile.invalid && Mobile.touched" style="color: red;">This Field is Required.</div>
    </div>
   
      <div class="form-group col-md-8">
        <input class="form-control" name="Email" #Email="ngModel" [(ngModel)]="custservice.selectedCustomer.Email" 
         placeholder="Email" required>
        <div class="validation-error" *ngIf="Email.invalid && Email.touched" style="color: red;">This Field is Required.</div>
      </div>
      <div class="row ml-1">
      <div class="form-group col-md-4">
        <button [disabled]="!customerForm.valid" type="submit" class="btn btn-lg btn-block btn-primary">
          <i class="fa fa-floppy-o"></i> Submit</button>
      </div>
      <div class="form-group col-md-4">
        <button type="button" class="btn btn-lg btn-block btn-default" (click)="resetForm(customerForm)">
          <i class="fa fa-repeat"></i> Reset</button>
      </div>
    </div>
  </form>
  • A hidden field is added for CustId property.
  • custservice.selectedCustomer is to add the field like Name, Address, Email and Mobile.
  • required attribute is added to Name and Address, Email and Mobile text boxes, so these two fields are mandatory to submit this form. When these text-boxes are invalid, ng-invalid and ng-dirty class will automatically added to it. so based on these classes we have implemented form validation. When these text boxes are not valid, customer form as whole is not valid, so we added conditional disable attribute to Submit Button.

when these text boxes are not valid, customer form as whole is not valid, so we added conditional disable attribute to Submit Button.

<button [disabled]="!customerForm.valid" type="submit" class="btn btn-lg btn-block btn-primary">
          <i class="fa fa-floppy-o"></i> Submit</button>
customer.component.ts

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms'
import { CustomerService } from '../shared/customer.service'
import { ToastrService } from 'ngx-toastr'
@Component({
  selector: 'app-customer',
  templateUrl: './customer.component.html',
  styleUrls: ['./customer.component.css']
 
})
export class CustomerComponent implements OnInit {
  custIdUpdate = null;  
  constructor(public custservice: CustomerService, private toastr: ToastrService) {
   
  }
  ngOnInit(): void {
    this.resetForm();
  }
  resetForm(form?: NgForm) {
    if (form != null)
      form.reset();
    this.custservice.selectedCustomer = {
      CustId: 0,
      Name: '',
      Address: '',
      Mobile: '',
      Email: ''
    }
  }

  onSubmit(form: NgForm) {
    console.log(form.value.CustId);
    if(form.value.CustId==null)
    {
      form.value.CustId=0;
    }
    this.custservice.selectedCustomer.CustId=form.value.CustId
    if (this.custservice.selectedCustomer.CustId == 0) {
      this.custservice.addCustomer(form.value)
        .subscribe(data => {
          form.value.CustId=0;
          this.resetForm(form);
          this.custservice.getCustomerList();
          this.toastr.success('New Record Added Succcessfully', 'Customer Registration');
        })
    }
    else {
      console.log("hello");
      this.custservice.updateCustomer(form.value.CustId, form.value)
      .subscribe(data => {
        this.resetForm(form);
        this.custservice.getCustomerList();
        this.toastr.info('Record Updated Successfully!', 'Customer Registration');
      });
    }
  }
}
  • Inside customer.component.ts file we write code for Insert, Update and Delete Operation.
  • Inject the CustomerService and ToastrService in the customer component.
  • Then on Submit form add the customer form. If the customer Id is null then it insert the data using call the service method else it update the record.
  • restForm function is used reset form controls value to initial stage, we called this function from reset button click event and from ngOnint  Lifecycle Hook to initialize the form.
  • Inside the form submit event function OnSubmit, we implement both insert and update operation based on CustomerID value. To show the success message,  we use ToastrService class object toastr.

Install package ngx-toastr

Before that we are going to install ngx-toastr from npm package. This package helps us to show notification message inside angular applications.

To install ngx-toastr follow the below command.

npm install ngx-toastr --save

Then add ToastrModule inside appmodule.ts file.

import { ToastrModule } from 'ngx-toastr';
@NgModule({
  declarations: [
  ],
  imports: [
      ToastrModule.forRoot()
  ],

Then add toastr.css style-sheet reference in .angular-cli.json file.

 "styles": [
              "src/styles.css",
              "node_modules/ngx-toastr/toastr.css"
            ],

Run application and you see the customer design form look like below. You can run the application using below command.

ng s --o

List Inserted Records and Delete Operation

Using customer-list component we add the list of all inserted customers and implement Delete operation. You can add following inside customer-list component.

customer-list.component.ts

import { Component, OnInit } from '@angular/core';
import { ToastrService } from 'ngx-toastr'
import { Customer } from '../shared/customer.model';
import { CustomerService } from '../shared/customer.service';
import { Observable, of, Subject } from 'rxjs';
@Component({
  selector: 'app-customer-list',
  templateUrl: './customer-list.component.html',
  styleUrls: ['./customer-list.component.css']
})
export class CustomerListComponent implements OnInit {
  allCustomers: Observable<Customer[]>;  

  constructor(public custservice: CustomerService,
                       private toastr : ToastrService) { }
  ngOnInit() {
    this.loadAllCustomers();  
  }
  loadAllCustomers() {  
    this.allCustomers = this.custservice.getCustomerList();  
  }  

  getCustomerList() {  
   this.custservice.getCustomerList();  
  }  
  showForEdit(cust: Customer) {
    this.custservice.selectedCustomer = Object.assign({}, cust);;
  }

  onDelete(id: number) {
    if (confirm('Are you sure to delete this record ?') == true) {
      this.custservice.deleteCustomer(id)
      .subscribe(x => {
        this.custservice.getCustomerList();
        this.toastr.warning("Deleted Successfully","Employee Register");
      })
    }
  }
}
  • Inside the customer-list.componenet.ts we have injected CustomerService and ToastrService Class.
  • Inside the ngOnint  Lifecycle hook, we called loadAllCustomers from CustomerService class. It will store customer collection from customer table inside customerList array. Now we can use this array to list customer collection.
customer-list.component.html

<table class="table table-sm table-hover">
    <tr *ngFor="let customer of custservice.CustomerList | async">
      <td>{{customer.Name}}</td>
      <td>{{customer.CustId}}</td>
      <td>
        <a class="btn" (click)="showForEdit(customer)">
          <i class="fa fa-pencil-square-o"></i>
        </a>
        <a class="btn text-danger" (click)="onDelete(customer.CustId)">
          <i class="fa fa-trash-o"></i>
        </a>
      </td>
    </tr>
  </table>
  • On the above we iterate the customer list bind when submit the record.
  • Also we use Edit and Delete operation with using method showForEdit() and onDelete()

Run the application again and the component design looks like this

  • When we click on pencil button it will call showForEdit function to populate corresponding record inside the customer form.
  • Using trash icon we implemented delete operation with onDelete function.

Final CRUD operation output

Let’s run the application and see the Final output of CRUD operation using Angular with ASP.NET Web API.

Source Code

Find the source code on the link.

Summary

This article explain Angular 10 application CRUD Operation using ASP .NET Web API. In this article we discuss how to create ASP .NET Web API project and how to consume the API inside in angular 10 application. In this example we use

  • ASP .NET Web API with Entity Framework code-first-approach
  • Angular 10 application with CRUD operation with Toastr message.

That’s a wrap for this article. I hope that it cleared about Angular 10 CRUD operations. Please write to us if have any.

Have you enjoyed this post and found it useful? If so, please consider supporting me:

Buy me a coffeeBuy me a coffee

Related Post

CRUD Operation in ASP.NET Web API with Entity Framework
CRUD-Operation-in-asp.net-Web-api

This blog explain CRUD Operation in ASP.NET Web API with Entity framework and then the web API check using POSTMAN Read more

How to create custom pipes in Angular
How to create custom pipes in Angular

A pipe takes in data as input and transforms it to a desired output. Simply you can say Pipes are Read more

How to use angular material in angular
How to use angular material in angular

UI component infrastructure and Material Design components for mobile and desktop Angular web applications.

CRUD Operation in ASP.NET Web API with Entity Framework

CRUD Operation in ASP.NET Web API with Entity Framework

In this article we are going to discuss CRUD Operation in ASP.NET Web API with Entity framework. we will learn how to perform CRUD operations with ASP.NET Web API and Entity Framework. We’ll go step by step in the form of a tutorial to set up a basic Web API project and we’ll use the code-first approach of Entity Framework to generate the database and perform CRUD operations and this ASP .NET Web API CRUD operation is to be test in Postman tool.

What is ASP .NET Web API ?

ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the . NET Framework.

“HTTP is not just for serving up web pages. HTTP is also a powerful platform for building APIs that expose services and data. HTTP is simple, flexible, and ubiquitous. Almost any platform that you can think of has an HTTP library, so HTTP services can reach a broad range of clients, including browsers, mobile devices, and traditional desktop applications.ASP.NET Web API is a framework for building web APIs on top of the .NET Framework.”

The above reference was taken from Microsoft Documents.

What is Entity Framework ?

Microsoft Entity Framework is an ORM (Object-relational mapping). The definition from Wikipedia is very straightforward for ORM and petty much self-explanatory,

“Object-relational mapping (ORM, O/RM, and O/R mapping tool) in computer science is a programming technique for converting data between incompatible type systems using object-oriented programming languages. This creates, in effect, a “virtual object database” that can be used from within the programming language.”

Create ASP .NET Web API Project

We do the project form scratch and Use Visual studio 2017 with .NET Version 4.6.1

ASP .NET Web API CRUD-Create Project
Choose ASP .NET Web Aplication
ASP .NET Web API CRUD-choose empty project
Choose Project template as Empty then choose Web API

After click the OK button it create the empty API project like below.

Customer API Project
Customer API Project
Create the Model Class

Here we create the model class that treated as entity of customer object that should be done database operations. Right click on the Models folder and add the class named as Customer with following properties.

  • Here we create the Customer Model with above properties.
  • [Table(“Customer”)] is belong to System.ComponentModel.DataAnnotations.Schema namespace. Here Customer is the table name that we want to create dynamically using EF code first.
  • CustId is the primary key of our entity table so we added as [Key]

After creating the Models class must rebuild the applications. To rebuild the project right click on Project and then click Rebuild.

Adding the API Controller

To do database operations to create, update,read and delete over model class we need to create the controller that should do the CRUD operations for us. To create the Controller right click on the Controllers folder and add a new Controller and in the prompt choose as Web API2 controller with actions, using Entity framework like below. Here we can use in-built entity framework scaffold technique to create CRUD query for us.

ASP .NET Web API CRUD-API2 Controller
Choose Web API2 Controller with actions using EF

After click the Add button a prompt will open to scaffold the model to create CRUD operations and choose Web API2 controller with actions, using Entity Framework.

ASP .NET Web API CRUD-Context class
Model Scaffold to create Web API Controller
  • In the Model Class choose the Model, in our case it is customer model class.
  • In the Data Context class, add + symbol and add the CustomerAPI Context.
  • Controller name in our case is CustomerController

After create the scaffold controller automatically it create the CRUD ( Create, Read, Update, Delete ) operations using Customer Model class and CustomerAPI Context class like below.

API Context Class

After adding the scaffold controller the API context class is also created inside the Model folder like below, that should contains the context of database schema. Here you can see CustomerAPIContext class implement the DbContext and base(“name=CustomerAPIContext”) is the name of the connection string to communicate with DB.

aspnet crud webapi-API Context
API Context
Entity Framework Code First Migrations

Code first migrations here help you to update the existing database with your newly added model classes and your existing database remains intact with the existing data.

  • Open Package manager console of the API project and type the command Enable-Migrations and hit enter.
Enable Migration

After adding this command a Migrations folder is generated like blow with crating the Configuration.cs class. This class is derived from DbMigrationsConfiguration class. This class contains a Seed method having the parameter as the context class that we got generated in the Models Seed is an overridden method that means it contains a virtual method in a base class and a class driven from DbMigrationsConfiguration can override that and add custom functionality.

ASP .NET Web API CRUD-Migrations
Migrations
  • The next step is to execute the command named “Add-Migrations”. In the package manager console. The command would be Add-Migrations Initial “Initial” is the parameter we have use, you may be use any other text as per your choice.
asnet web api crud-Add migration initial
Add migration initial

After executing the command it adds a new file with the name “Initial” prefixed with the date time stamp. It prefixes the date time stamp so that it could track the various migrations added during development and segregate between those. Open the file and we see the class named “Initial” deriving from DbMigration class. This class contains two methods that are overridden from DbMigration class i.e. the base class. The method names are Up() and Down().

aspnet crud weba pi migration initialal
Migration

The Up method is executed to add all the initial configuration to the database and contains the create command in LINQ format. This helps to generate tables and all the modifications done over the model. Down command is the opposite of Up command. The code in the file is self-explanatory. The Up command here is having the code that creates the Students table and setting Id as its primary key. All this information is derived from the model and its changes.

  • The final command that creates the database and respective tables out of our context and model. It executes the Initial migration that we added and then runs the seed method from the configuration class. This command is smart enough to detect which migrations to run. For example it will not run previously executed migrations and all the newly added migrations each time will be taken in to account to be executed to update the database. It maintains this track as the database firstly created contains an additional table named __MigrationHistory that keeps track of all the migrations done.
  • The command is Update-Database
aspnetcrud webapi Update-Database
Update-Database

After the command execution, it creates the database in the specified server as per your server and adds the corresponding connection string to the Web.Config file. The name of the connection string is the same as the name of our context class and that’s how the context class and connection strings are related.

<connectionStrings>
    <add name="CustomerAPIContext" connectionString="Data Source=ServerName; Initial Catalog=customers; User ID=sa;password=*****;"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

Now it automatically create the database named as “customers” with table name “customer”. Also it holds the migration history in the tables.

Exploring the Generated Database

You can see when navigate to SQL Server, find their the database is created for us.

aspnet webapi crud
ASP NET Web API CRUD Operation DB explorer

Test the CRUD operation using Postman

What is Postman ?

Postman is an API(application programming interface) development tool which helps to build, test and modify APIs. Almost any functionality that could be needed by any developer is encapsulated in this tool. It is used by over 5 million developers every month to make their API development easy and simple. It has the ability to make various types of HTTP requests(GET, POST, PUT, PATCH). It can be downloaded into the system or you can use it bu using Google chrome extension.

Web API Create method test using Postman

Open the Postman tool and run the application and here we want to create the customer data that means we push the customer information so like below we can push the data.

  • Here http://localhost:49243/api/Customers is the URL to create CRUD operation.
  • /api/Customers customers is the controller that we have created.
  • Here we want push the information to database so need to choose POST method in Postman.
  • In the Body section append the inputs in json format as formatted above.
  • Click the send button and then the data is pushed to database using post method like below;
ASP NET WEB API POST Operation
aspnet web api crud post method
Web API CRUD Post method
asp net crud web api post method insertion
Web API Post method Insertion
Web API READ method test using Postman

Her we see how to read the data using postman in GET method. In postman we can change the method type to GET and call the below mentioned Web API URL.

  • Below you can see we call the same URL http://localhost:49243/api/Customers with changing the method as GET to READ the data.
  • It call the get method and fetch the result set as JSON format in below.
ASP NET Web API GET Customers data
asp net crud web api get result
GET Method call
Web API UPDATE method test using Postman

Her we see how to update the data using postman in PUT method. In postman we can change the method type to PUT and call the below mentioned Web API URL.

  • Below you can see we call the same URL http://localhost:49243/api/Customers with changing the method as PUT to UPDATE the data by passing the Id.
  • To get the corresponding Id it can update the request.
ASP NET WEB API Update Operation Code
asp net crud web api update result
ASP NET WEB API Update Operation result
Web API DELETE method test using Postman

Her we see how to delete the data using postman in DELETE method. In postman we can change the method type to DELETE and call the below mentioned Web API URL.

  • Below you can see we call the same URL http://localhost:49243/api/Customers with changing the method as DELETE to delete the data from database.
  • To delete the request we follow the below code in controllers.
ASP NET Web API Delete Operation
ASP NET Web API Delete Result
  • On above we pass the delete item id as 2 so it delete the record and for confirmation we bind the deleted data inn response body tag.
  • When we move to database and refresh the table and find their the item is deleted for id 2.
asp net crud web api delete operation result
DELETE Operation result

Web API GET by ID method test using Postman

ASP NET Crud Operation Customer By ID
  • By passing only Id you can fetch the result of the one customer.

Video Reference

Summary

In this article we explained how to create APP .NET Web API using entity framework code first approach and how the crud operation is test using Postman tool. If have any suggestion for improvement to this article then feel to free write to us.

How to use angular material in angular
How to use angular material in angular

UI component infrastructure and Material Design components for mobile and desktop Angular web applications.

How to create custom pipes in Angular
How to create custom pipes in Angular

A pipe takes in data as input and transforms it to a desired output. Simply you can say Pipes are Read more

How to read external JSON file in Jquery AJAX
Javascript-Jquery-Ajax

This article explain how to read external json file. There are many ways to store JSON data in our application. Read more

Export data into Excel in ASP.NET MVC
Export-data-into-Excel

In this example we learn how to export the data into MS Excel in ASP.NET MVC without using any 3rd Read more

Pin It on Pinterest