Redis Caching in ASP.NET Core- Depth in Distributed Caching

Redis Caching in ASP.NET Core- Depth in Distributed Caching

In this article, we will learn how to use Redis caching in an ASP.Net Core Web API. Before starting this article please must visit our previous article In-Memory Caching in ASP.NET Core where we discussed about Caching , In-Memory Caching in ASP.NET Core, and other concepts related to caching. In this article, we will talk about Distributed Caching, Redis, Setting up Redis Caching in ASP.NET Core.

Find SourceCode

Prerequisites

– Basic knowledge of Caching & In-memory of Caching
– Visual Studio 2019
– .NET Core SDK 5.0 ( You can use SDK 3.1 )
Redis Caching in ASP.NET Core- Depth in Distributed Caching
Tweet

What is Distributed Caching ?

A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service or a server farm.

Like an in-memory cache, it can improve the ASP.Net Core application response time quite drastically. However, the implementation of the Distributed Cache is application-specific. This means that there are multiple cache providers that support distributed caches. A few of the popular ones are Redis and NCache.

Pros of Distributed Caching

A distributed cache has several advantages over other caching scenarios where cached data is stored on individual app servers. When cached data is distributed, the data:

  • Is coherent (consistent) across requests to multiple servers.
  • Multiple Applications / Servers can use one instance of Redis Server to cache data. This reduces the cost of maintenance in the longer run.
  • The cache would not be lost on server restart and application deployment as the cache lives external to the application.
  • It does not use the local server’s resources.

Cons of Distributed Caching

There are two main disadvantages of the distributed caching:

  • The cache is slower to access because it is no longer held locally to each application instance.
  • The requirement to implement a separate cache service might add complexity to the solution

What is Redis Caching ?

Redis(Remote DIctionary Server) is an open source, in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams.

It’s a NoSQL Database as well and is being used at tech giants like Stackoverflow, Flickr, Github, and so on. Redis is a great option for implementing a highly available cache to reduce the data access latency and improve the application response time. As a result, we can reduce the load off our database to a very good extent.

Let’s understand in a better way of Redis cache,

  • User requests a user object.
  • App server checks if we already have a user in the cache and return the object if present.
  • App server makes a HTTP call to retrieve the list of users.
  • Users service returns the users list to the app server.
  • App server sends the users list to the distributed (Redis) cache.
  • App server gets the cached version until it expires (TTL).
  • User gets the cached user object.

IDistributedCache Interface

ASP.NET Core provides IDistributedCache interface to interact with the distributed caches including Redis.. IDistributedCache Interface provides you with the following methods to perform actions on the actual cache.

  • GetAsync – Gets the Value from the Cache Server based on the passed key.
  • SetAsync – Accepts a key and Value and sets it to the Cache server
  • RefreshAsync – Resets the Sliding Expiration Timer (more about this later in the article) if any.
  • RemoveAsync – Deletes the cache data based on the key.

How to setup Redis in a Windows Machine

To setup Redis in a windows machine, There is Redis open source Github Repo, You could also use the MSI Executable file.

Extract the highlighted zip folder and open redis-server.exe file.

Redis cache command

Now, the Redis server is up and running. We can test it using the redis-cli command.

Open a new command prompt and run redis-cli on it and try the following commands:

Now that we installed the Redis-server and saw that it is working properly, we can modify the API to use Redis-based distributed caching.

Redis CLI Commands

Setting a Cache Entry
-> Set name "corespider"
OK
Getting the cache entry
-> Get name
"corespider"
Deleting a Cache Entry
-> Get name
"corespider"
-> Del name
(integer)1

Integrating Redis Cache In ASP.NET Core

In the previous example of In-Memory Caching we created the ASP.NET Core Web API project. This API is connected to DB via Entity Framework Core and return the customer list.

MAKE Sure that Redis Server is up and running in the background.

  • Install the below package using Nuget Package manager console OR you can install package using Nuget search.
Install-Package Microsoft.Extensions.Caching.StackExchangeRedis
  • To support the Redis cache let’s configure the cache in startup.cs/ConfigureServices method.

By default, Redis runs on the local 6379 port. To change this, open up Powershell and run the following command.

./redis-server --port {your_port}

services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost:4450";
});

Implement Redis Cache memory in Controller

        private readonly ApplicationDbContext _context;
        private readonly IMemoryCache memoryCache;
        private readonly IDistributedCache distributedCache;
        public CustomersController(ApplicationDbContext context, IMemoryCache memoryCache, IDistributedCache distributedCache)
        {
            _context = context;
            this.memoryCache = memoryCache;
            this.distributedCache = distributedCache;
        }
        // GET: api/Customers
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Customer>>> GetCustomers()
        {
            var cacheKey = "Allcustomer";
            string serializedCustomerList;
            var customerList = new List<Customer>();
            var redisCustomerList = await distributedCache.GetAsync(cacheKey);
            if (redisCustomerList != null)
            {
                serializedCustomerList = Encoding.UTF8.GetString(redisCustomerList);
                customerList = JsonConvert.DeserializeObject<List<Customer>>(serializedCustomerList);
            }
            else
            {
                customerList = await _context.Customers.ToListAsync();
                serializedCustomerList = JsonConvert.SerializeObject(customerList);
                redisCustomerList = Encoding.UTF8.GetBytes(serializedCustomerList);
                var options = new DistributedCacheEntryOptions()
                    .SetAbsoluteExpiration(DateTime.Now.AddMinutes(10))
                    .SetSlidingExpiration(TimeSpan.FromMinutes(2));
                await distributedCache.SetAsync(cacheKey, redisCustomerList, options);
            }
            return customerList;
        }
  • Line #4-8: We use the required constructor in the controllers.
  • Line #14: We set the key internally in the code.
  • Line #17: Access the distributed cache object to get data from Redis using the key “AllCustomer”
  • Line #18 -23: If the key has a value in Redis, then convert it to a list of Customers and send back the data. If the value does not exist in Redis, then access the database via efcore, get the data and set it to redis.
  • Line #25-31: The data will be stored in Redis as a byte array. We will be converting this array of a string. Converts the string to an object of type List.
  • SlidingExpiration: Gets or sets how long a cache entry can be inactive (e.g. not accessed) before it will be removed. This will not extend the entry lifetime beyond the absolute expiration (if set).
  • AbsoluteExpiration: Gets or sets an absolute expiration date for the cache entry.

Test the Redis Cache in Postman

Let’s open the postman tool and test the cache performance.

In the first API call took about 6850 ms to return a response. During the first call the cache for customerList also would be set by our API onto the Redis server. Thus, the second call would be direct to the Redis cache, which should reduce the response time significantly. Let’s see that only takes 33 ms.

How to conditionally inject an IDistributedCache implementation of MemoryDistributedCache during local development?

You are using the key-value caching functionality of Redis. You are coding an Azure function (could be an ASP.NET Core Web app) and you want to develop and debug the code. Do you need to install Redis locally? Not neccessary. Through a couple of lines of clever DI, you can “fool” your classes to use the MemoryDistributedCache implementation of the interface IDistributedCache.

In this snippet we are checking for the the value of an environment variable and conditionally injecting the desired implementation of IDistributedCache

[TestMethod]
        public void Condition_Injection_Of_IDistributedCache()
        {
            var builder = new ConfigurationBuilder();
            builder.AddJsonFile("settings.json", optional: false);
            Config = builder.Build();
            ServiceCollection coll = new ServiceCollection();
            if (System.Environment.GetEnvironmentVariable("localdebug") == "1")
            {
                coll.AddDistributedMemoryCache();
            }
            else
            {
                coll.AddStackExchangeRedisCache(options =>
                {
                    string server = Config["redis-server"];
                    string port = Config["redis-port"];
                    string cnstring = $"{server}:{port}";
                    options.Configuration = cnstring;
                });
            }
            var provider = coll.BuildServiceProvider();
            var cache = provider.GetService<IDistributedCache>();
        }

How do we benchmark the performance of Redis cache?

The primary motivation for using a distributed cache is to make the application perform better. In most scenarios the central data storage becomes the bottleneck. Benchmarking the distributed cache gives us an idea of how much latency and throughput to expect from the cache for various document sizes.

Find Source Code

Summary

In this detailed article, we have learnt about Redis Caching in ASP.Net Core. We discussed Caching, the Basics, In-Memory Caching, Implementing In-Memory Caching in ASP.NET Core etc.

That’s a wrap for this article. I hope that it cleared about In-Memory Caching in ASP.NET Core-Basic guide of Caching. 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

References

Latest Post

In-Memory Caching in ASP.NET Core-Basic guide of Caching
in memory caching

This article explain about In-Memory Caching in ASP.NET Core, We discussed here Caching, the Basics, In-Memory Caching, Implementing In-Memory Caching Read more

CQRS pattern with MediatR in ASP.NET Core 5.0
CQRS pattern with MediatR in ASP.NET Core 5.0

This article explain CQRS design pattern with MediatR in ASP.Net Core 5.0. CQRS is a design pattern that separated the Read more

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

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

Integrate Razorpay Payment Gateway in ASP.NET Core

Integrate Razorpay Payment Gateway in ASP.NET Core

In this article we will learn how to Integrate Razorpay Payment Gateway in ASP.Net Core. We discuss here about Razor Pay with learn how to integrate it in ASP.Net Core MVC.  Please go through our previous article Deploy ASP.NET Core Web App in Azure Virtual Machine. At the end of this article you can see output like this, we integrate the Razorpay in ASP.Net Core MVC.

Source Code

Prerequisites

— Razorpay payment Gateway Account ( You can check with free account)
— Visual Studio 2019

What is Razorpay Payment Gateway?

A payment gateway is an online service that authorizes and processes payments for online businesses. It is the glue between the customer and the merchant. Some popular payment Gateway are below,

  • PayPal
  • Stripe
  • Authorize.net
  • Amazon Payments
  • 2Checkout

The Razorpay Payment Gateway enables to accept payments via debit card, credit card, net banking, UPI and popular supported wallets.

Creating Razorpay Payment Gateway Account Setup

  • Let’s signup Razorpay payment Gateway using this link, You can sign up using your Google account also.
  • After sign up it ask the “business type” along with your name and mobile number.
  • Then move Razorpay account dashboard and go to Settings then API Keys Tab and Generate a key for the selected mode (Test or Live) as shown below:
Razorpay API keys

Integrate Razorpay Payment Gateway in ASP.NET Core

  • Let’s create ASP.NET Core MVC 5.0 project using Visual studio 2019.

Add Razorpay package in Nuget

Create Model/Entity Class

Let’s create the 2 entitles that holds the Payment Request and Merchant Order details.

public class MerchantOrder
    {
        public string OrderId { get; set; }
        public string RazorpayKey { get; set; }
        public int Amount { get; set; }
        public string Currency { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string PhoneNumber { get; set; }
        public string Address { get; set; }
        public string Description { get; set; }
    }
public class PaymentRequest
    {
        [Required]
        public string Name { get; set; }
        [Required]
        public string Email { get; set; }
        [Required]
        public string PhoneNumber { get; set; }
        [Required]
        public string Address { get; set; }
        [Required]
        public int Amount { get; set; } 
    }

Create the Business Logic to Integrate Razorpay

Create the Service method that holds the business logic. Let’s create a folder name as “Service” inside the Razorpay project.

Create Interface

public interface IPaymentService
    {
         Task<MerchantOrder> ProcessMerchantOrder(PaymentRequest payRequest);
         Task<string> CompleteOrderProcess(IHttpContextAccessor _httpContextAccessor);
    }

Implement Interface inside “PaymentService”

public class PaymentService : IPaymentService
    {
       
        public Task<MerchantOrder> ProcessMerchantOrder(PaymentRequest payRequest)
        {
            try
            {
                // Generate random receipt number for order
                Random randomObj = new Random();
                string transactionId = randomObj.Next(10000000, 100000000).ToString();

                Razorpay.Api.RazorpayClient client = new Razorpay.Api.RazorpayClient("rzp_test_8P7RhnsImxd2OR", "kD8tw7ECYsTTZnx0OyrKI4kh");
                Dictionary<string, object> options = new Dictionary<string, object>();
                options.Add("amount", payRequest.Amount * 100);
                options.Add("receipt", transactionId);
                options.Add("currency", "INR");
                options.Add("payment_capture", "0"); // 1 - automatic  , 0 - manual
                //options.Add("Notes", "Test Payment of Merchant");

                Razorpay.Api.Order orderResponse = client.Order.Create(options);
                string orderId = orderResponse["id"].ToString();

                MerchantOrder order = new MerchantOrder
                {
                    OrderId = orderResponse.Attributes["id"],
                    RazorpayKey = "rzp_test_8P7RhnsImxd2OR",
                    Amount = payRequest.Amount * 100,
                    Currency = "INR",
                    Name = payRequest.Name,
                    Email = payRequest.Email,
                    PhoneNumber = payRequest.PhoneNumber,
                    Address = payRequest.Address,
                    Description = "Order by Merchant"
                };
                return Task.FromResult(order);
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        public async Task<string> CompleteOrderProcess(IHttpContextAccessor _httpContextAccessor)
        {
            try
            {
                string paymentId = _httpContextAccessor.HttpContext.Request.Form["rzp_paymentid"];

                // This is orderId
                string orderId = _httpContextAccessor.HttpContext.Request.Form["rzp_orderid"];

                Razorpay.Api.RazorpayClient client = new Razorpay.Api.RazorpayClient("rzp_test_8P7RhnsImxd2OR", "kD8tw7ECYsTTZnx0OyrKI4kh");

                Razorpay.Api.Payment payment = client.Payment.Fetch(paymentId);

                // This code is for capture the payment 
                Dictionary<string, object> options = new Dictionary<string, object>();
                options.Add("amount", payment.Attributes["amount"]);
                Razorpay.Api.Payment paymentCaptured = payment.Capture(options);
                string amt = paymentCaptured.Attributes["amount"];
                return paymentCaptured.Attributes["status"];
            }
            catch (Exception)
            {
                throw;
            }
        }
    }

Code Explanation

  • Line #4 : ProcessMerchantOrder is use to collect the order details.
  • Line #9-10 : Random transaction id is generate.
  • Line #12-21 : This is use for to collect and generate the order. Here we need to use Razor Key and Secret Key.
  • Line #23-35 : Is used to return the Order details.
  • Line #43-61 : According to the payment info it complete the payment.

Add the Dependency services inside Startup class

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddTransient<IPaymentService, PaymentService>();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        }

Create a Controller as PaymentController

public class PaymentController : Controller
    {
        private readonly ILogger<PaymentController> _logger;
        private readonly IPaymentService _service;
        private IHttpContextAccessor _httpContextAccessor;
        public PaymentController(ILogger<PaymentController> logger, IPaymentService service, IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            _service = service;
            _httpContextAccessor = httpContextAccessor;
        }
        public IActionResult Index()
        {
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> ProcessRequestOrder(PaymentRequest _paymentRequest)
        {
            MerchantOrder _marchantOrder = await _service.ProcessMerchantOrder(_paymentRequest);
            return View("Payment", _marchantOrder);
        }
        [HttpPost]
        public async Task<IActionResult> CompleteOrderProcess()
        {
            string PaymentMessage =await _service.CompleteOrderProcess(_httpContextAccessor);
            if (PaymentMessage == "captured")
            {
                return RedirectToAction("Success");
            }
            else
            {
                return RedirectToAction("Failed");
            }
        }
        public IActionResult Success()
        {
            return View();
        }

        public IActionResult Failed()
        {
            return View();
        }
    }

Code Explanation

  • Line #3-11 : The controller implements dependency injection.
  • Line #17-20 : Process the merchant order information.
  • Line #23-38 : This is use for the payment is success or failure.

Create Require Razor Pay cshtml

Index.cshtml that hold the payment page information.

@model Razorpay.Integration.Models.PaymentRequest
@{
    ViewData["Title"] = "Payment Page";
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <form class="well form-horizontal" asp-action="ProcessRequestOrder" method="post" id="contact_form">
        <center><h2><b>Razorpay Payment Gateway Integration</b></h2></center>
        <div class="form-group">
            <label class="col-md-4 control-label">Customer Name</label>
            <div class="col-md-4 inputGroupContainer">
                <div class="input-group">
                    <span class="input-group-addon"><i class="fa fa-user"></i></span>
                    <input placeholder="Name" class="form-control" type="text" asp-for="Name" autocomplete="off" required>
                </div>
            </div>
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label">E-Mail</label>
            <div class="col-md-4 inputGroupContainer">
                <div class="input-group">
                    <span class="input-group-addon"><i class="fa fa-envelope" style="font-size:11px"></i></span>
                    <input placeholder="E-Mail Address" class="form-control" type="text" asp-for="Email" autocomplete="off" required>
                </div>
            </div>
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label">Phone Number</label>
            <div class="col-md-4 inputGroupContainer">
                <div class="input-group">
                    <span class="input-group-addon"><i class="fa fa-phone"></i></span>
                    <input placeholder="Phone" class="form-control" type="text" asp-for="PhoneNumber" autocomplete="off" required>
                </div>
            </div>
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label">Address</label>
            <div class="col-md-4 inputGroupContainer">
                <div class="input-group">
                    <span class="input-group-addon"><i class="fa fa-address-book-o" style="font-size:11px"></i></span>
                    <input placeholder="Address" class="form-control" type="text" asp-for="Address" autocomplete="off" required>
                </div>
            </div>
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label">Amount (INR)</label>
            <div class="col-md-4 inputGroupContainer">
                <div class="input-group">
                    <span class="input-group-addon"><i class="fa fa-inr" style="font-size:19px"></i></span>
                    <input placeholder="Amount (INR)" class="form-control" type="text" asp-for="Amount" autocomplete="off" required>
                </div>
            </div>
        </div>
        <div class="form-group">
            <label class="col-md-4 control-label"></label>
            <div class="col-md-4" style="text-align:center;">
                <button type="submit" class="btn btn-warning">SUBMIT <span class="glyphicon glyphicon-send"></span></button>
            </div>
        </div>
    </form>

After input all the information then click on Submit button it redirect to payment.cshtml page like below;

@model Razorpay.Integration.Models.MerchantOrder
<button id="RzP_btn" hidden>Pay</button>
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
<script>
var options = {
    "key": "@Html.DisplayFor(model => model.RazorpayKey)", // Enter the Key ID generated from the Dashboard
    "amount": "@Html.DisplayFor(model => model.Amount)", // Amount is in currency subunits. Default currency is INR. Hence, 50000 refers to 50000 paise
    "currency": "@Html.DisplayFor(model => model.Currency)",
    "name": "@Html.DisplayFor(model => model.Name)",
    "description": "@Html.DisplayFor(model => model.Description)",
    "image": "https://avatars.githubusercontent.com/u/65504583?v=4", // You can give your logo url
    "order_id": "@Html.DisplayFor(model => model.OrderId)",
    "handler": function (response){
        // After payment successfully made response will come here
        // Set the data in hidden form
        document.getElementById('rzp_paymentid').value = response.razorpay_payment_id;
        document.getElementById('rzp_orderid').value = response.razorpay_order_id;
        // // Let's submit the form automatically
        document.getElementById('rzp-paymentresponse').click();
    },
    "prefill": {
        "name": "@Html.DisplayFor(model => model.Name)",
        "email": "@Html.DisplayFor(model => model.Email)",
        "contact": "@Html.DisplayFor(model => model.PhoneNumber)"
    },
    "notes": {
        "address": "@Html.DisplayFor(model => model.Address)"
    },
    "theme": {
        "color": "#F37254"
    }
};
    var rzp1 = new Razorpay(options);
    //<!-- onload function -->
    window.onload = function(){
        document.getElementById('RzP_btn').click();
    };
    document.getElementById('RzP_btn').onclick = function(e){
    rzp1.open();
    e.preventDefault();
}
</script>
<form action="CompleteOrderProcess" method="post" asp-antiforgery="true">
    <input type="hidden" id="rzp_paymentid" name="rzp_paymentid" />
    <input type="hidden" id="rzp_orderid"  name="rzp_orderid"/>
    <button type="submit" id="rzp-paymentresponse" class="btn btn-primary" hidden>Submit</button>
</form>

That’s it. Let run the application and see the result.

Source Code

Source Code

Summary

This article explained about Integrate Razorpay Payment Gateway in ASP.Net Core. We discussed here about Razorpay and learned how to Integrate Razorpay Payment Gateway in ASP.Net Core.

Before implement the Razprpay into Production, please review about the product, features and security.

That’s a wrap for this article. I hope that it cleared about Integrate Razorpay Payment Gateway in ASP.NET Core. 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

Deploy ASP.NET Core Web App in Azure Virtual Machine
Deploy ASP.NET Core Web App in Azure Virtual Machine

This article explain about Deploy ASP.NET Core Web App in Azure Virtual Machine. We discuss here how to create VM Read more

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

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

This article explain how to send Email in ASP.NET Core using Mailkit. It is open-source cross-platform library that can be 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

Deploy ASP.NET Core Web App in Azure Virtual Machine

Deploy ASP.NET Core Web App in Azure Virtual Machine

In this article we will learn about Deploy ASP.Net Core Web App in Azure Virtual Machine. We discuss here more about Azure Virtual machine and learn how to create virtual machine in Azure step by step. After creation of Virtual machine(VM) we deploy the ASP.NET Core Web App in Azure Virtual machine. Please go through our previous article CQRS pattern with MediatR in ASP.NET Core 5.0.

What is Virtual Machine ?

A Virtual Machine(VM), is no different than any other physical computer like a laptop, smart phone or server. It has a CPU, memory, disks to store your files and can connect to the internet if needed. VMs are often thought of as virtual computers or software-defined computers within physical servers, existing only as code.

For more details about Virtual machine visit https://azure.microsoft.com/en-in/overview/what-is-a-virtual-machine/

Prerequisites to Deploy ASP.NET Core Web App in Azure VM

– Azure Account
– Visual Studio 2019 ( You can check with prev. version of VS)
– DotNet SDK 5.0 & Bundle (We consider .NET Core 5)
– Web Deploy bundle in IIS

How to Create Azure Virtual Machine(VM) ?

Let’s discuss how to create Azure Virtual Machine(VM) in step by step.

Sign-up Azure Account

  • We need to have a subscription in Azure, if we don’t have an account we can get a free one here. If you want to learn how to create Azure account then please follow the link How to sign-up for an Azure free account.
  • After creation of Azure portal login with your credential.
  • Go to the Azure portal and find the Virtual Machines resource and create a new one.
Azure virtual machine

Steps to Create Virtual Machine(VM)

After click on Virtual Machines link it navigate to below page. We need to filled up with below information.

  • Subscription – You need to select the subscription according to your list. (We have Free Trial Subscription)
  • Resource Group – You need to select Resource Group, if the resource are not available create a new one according to your location.
  • VM Name– Input the VM name according to your convenient.
  • Region – Select the region according to nearest GEO location for better availability means better performance.
  • Image– We select Windows Server 2019, according to your choice you can select Windows/Linux.
  • Size– Select the VM size, it depends upon the RAM with price range.
  • Credentials– Set your credentials, you can set the credential according to yours.
  • Inbound Ports – Select Inbound Port as HTTP, HTTPS, RDP(Remote Desktop).
Azure virtual machine creation

That’s it then click on Review+Create button, it navigate to price of VM like below then hit create button.

Azure VM price

Now you can see the Virtual Machine(VM) set up in Azure is completed.

Connect Virtual Machine(VM) using RDP(Remote Desktop Protocol)

To connect VM using RDP, Open VM and then click on connect button

Azure-virtual-machine-connect-rdp

Download the RDP file it download the Remote Desktop connection Protocol, click on that to login using the VM Credential.

I have faced the Remote Desktop connection issue like below, to overcome this follow below steps.

After creation of Inbound rules, now try again with downloaded RDP, then you can see, connection is success and it ask the credentials. Using the credentials you can able to logged in VM.

Installing IIS (Web Server) in VM

Add roles and features in the Server Manager Dashboard,

When starting the setup wizard, we must accept the default settings in the Installation Type and Server Selection sections. In the Server Roles section, we will select Web Server (IIS) and accept the additional required installation of IIS Management Console.

Once the installation is complete there are two important considerations,

  • IIS is installed and runs with the internal firewall rule created for port 80.
  • Web Management Service is installed with the internal firewall rule created for port 8172.

Install Web Deploy, .NET Core SDK & Bundle in VM

Let’s install Web deploy in virtual machine following the link.

Download and Install both SDK and hosting bundle of ASP.NET Core using this link.

Now everything is ready to configure the application in VM. Let’s open the IIS

Settings in Azure Virtual Machine from the portal

 The Windows Server machine in Azure is ready. All we need is two important additional steps. It’s about assigning the DNS (Domain Name System) of the virtual machine and enabling one of the ports to work with Web Deploy.

Configure DNS for the virtual machine

To perform this configuration, we need to go to the general section of the virtual machine in the DNS Name option and click Configure. Here we will define a unique DNS name (A green tick appears when the name is validated).

Configure virtual machine inbound firewall rules

For the configuration in this section, we need to go to the Networking section within the VM resource in Azure and select the Add inbound port rule option to create a new firewall rule.

Web deploy

Deploy an ASP.NET Core 5 Web App in Azure Virtual Machine

  • Using VS 2019 let’s create a sample web App in ASP.NET Core.
  • So, now our VM is ready then we are going to publish the file using Visual studio right way to VM.

When we hit the publish button, it ask us the credentials again like below. Give the credentials and click on OK button.

When you navigate to Virtual machine path you can see the required file is

You can see now we can access our deployed site in Azure.

Summary

This article explained about Deploy ASP.Net Core Web App in Azure Virtual Machine. We discussed here about Azure Virtual machine and learned how to create virtual machine in Azure step by step, then deployed the ASP.NET Core Web App in Azure Virtual machine.

That’s a wrap for this article. I hope that it cleared about Deploy ASP.NET Core Web App in Azure Virtual Machine. 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

Integrate Razorpay Payment Gateway in ASP.NET Core
Integrate Razorpay Payment Gateway in ASP.NET Core

This article explain about Integrate Razorpay Payment Gateway in ASP.NET Core. We discuss here how to implement Razorpay gateway in Read more

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

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

This article explain how to send Email in ASP.NET Core using Mailkit. It is open-source cross-platform library that can be 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

ASP.NET Core Web API with MongoDB CRUD- Beginner’s Guide

ASP.NET Core Web API with MongoDB CRUD- Beginner’s Guide

In this article we discuss about how to use MongoDB in ASP.NET Core Web API. It’s complete beginners tutorial to learn how we can integrate mongoDB in ASP.NET Core web API project. Now-a-days we hear a common word about NoSQL databases. These are being very strongly promoted by all vendors. One of the most common NoSQL databases these days is MongoDB. In this article we will discuss what a NoSQL database is, when it must be used and then we will look at an example to install, create and populate this database. Finally, we will look at how to access data from this database using a ASP.NET Core Web API. Also please read our previous article How to send Email in ASP.NET Core-Beginner’s Guide.

Navigate to source code

What is a NoSQL database?

NoSQL database is a collection of documents with no real defined structure as in an RDBMS or SQL database. That means that we do not have any pre-defined columns as we do have in a SQL table. We simply store each row with its own number of columns or data fields as we may call them.

Advantages of NoSQL database?

  • The common advantages of NoSQL database is the data for each document is in one place and faster to read.
  • As there is no pre-defined structure we can store documents with different fields in one place and do not have to worry about adding new columns each time where most rows could contain NULLS as in a SQL database. Also, it saves us from creating new tables with relationships.

What is MongoDB?

MongoDB is one of the most common NoSQL databases. MongoDB can be downloaded and run from your desktop computer. It runs as a service. It also comes with a client called “MongoDB Compass Community”. This is a nice compact client which allows you to connect to the instance running, view the databases, collections, and documents inside it. It also allows you to create new databases, new collections inside the database, and new documents inside the collection using the JSON format. Being a Microsoft developer, another well known NoSQL database is Cosmos DB in addition to the tables storage mechanism in Microsoft Azure.

Installing MongoDB Server

MongoDB allows to host our own instance locally in our infrastructure. They offer Enterprise as well as community editions of their installable server. You will have to install both the server and a GUI Application (MongoDB Compass) to manage the MongoDB, very similar to SQL Management Studio.

Download MongoDB server.
MongoDb downlead

Once you have downloaded the MSI package, you can install it as shown below:

mongoDB msi file

After installation, Open up MongoDB Compass. With Compass, you could specify the connection string to any authorized server and start browsing the database quite easily, But since we have no connection string with us, we can connect to the local MongoDB Server. For this you don’t have to specify the connection string, just press CONNECT.

This gets you connected to the localhost:27017 port where your default mongodb service is running.

mongoDb compass

After click on connect you can navigate to this below screen.

Create Database

Input database name as per your choice and set the collection name.

Let’s try to add a new Document to the Books Collection. Select the Books Collection and Add Data -> Insert Document.

{
  "name": "Clean Architecture in .NET Core",
  "price" : 1000,
  "category" : "Computers",
  "author" : "JT"
}

After click on insert button the JSON collection data is inserted in Books collection. You can note that the ID gets generated automatically with a random GUID.

MongoDB In ASP.NET Core Web API – Getting Started

MongoDB is highly cross platform and can be seamlessly integrated with ASP.NET Core to take the maximum advantage of this awesome document based NOSQL Database. Let’s walkthrough step by step on working with MongoDB in ASP.NET Core. We will be setting up MongoDB Server and ultimately building a ASP.NET Core 5.0 WebAPI that does CRUD operations on a MongoDB Instances.

Create ASP.NET Core Web API project

Open Visual stuidio and create a new ASP.NET Core Web API and select target framework as 5.0 and also tick Open API support to enable swagger on our project. Using swagger we can test the API.

Add MongoDB Driver package in the project

Let’s add MongoDB package using package manager console.

Install-Package MongoDB.Driver

Create the Model class to manage CRUD

Let’s create the model class inside the Entity folder named as Books.

public class Books
    {
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string id { get; set; }
        public string name { get; set; }
        public int price { get; set; }
        public string category { get; set; }
        public string author { get; set; }
    }
  • Line no. 3&4 – For Id property, we set the primary key of MongoDB document, this is represented as [BsonId]. MongoDB recognizes object Id and not string/int as the primary key. Thus we have to manually set the property so that MongoDB converts the string to object Id.
  • Line no. 5-9 – The properties of Books collection that we are added.

Add Connection string in Appsettings.json file

"BooksConnectionSettings": {
    "BooksCollectionName": "Books",
    "ConnectionString": "mongodb://localhost:27017",
    "DatabaseName": "BooksDB"
  }
  • Line #1 : Connection setting name declare.
  • Line #2-4 : We declared connection collection name, connection string and Database name.

Add a configuration class

Let’s add a configuration class inside configuration folder.

public class BooksConfiguration
    {
        public string BooksCollectionName { get; set; }
        public string ConnectionString { get; set; }
        public string DatabaseName { get; set; }
    }

Add the Service class to complete CRUD

Let’s create a Interface to hold the CRUD operation method.

public interface IBookService
    {
        Task<List<Books>> GetAllAsync();
        Task<Books> GetByIdAsync(string id);
        Task<Books> CreateAsync(Books book);
        Task UpdateAsync(string id, Books book);
        Task DeleteAsync(string id);
    }

Create the Book service class and implement the IBookService inside it.

using CoreAPI.Mongo.Configuration;
using CoreAPI.Mongo.Entity;
using MongoDB.Driver;
public class BookService: IBookService
    {
        private readonly IMongoCollection<Books> _book;
        private readonly BooksConfiguration _settings;
        public BookService(IOptions<BooksConfiguration> settings)
        {
            _settings = settings.Value;
            var client = new MongoClient(_settings.ConnectionString);
            var database = client.GetDatabase(_settings.DatabaseName);
            _book = database.GetCollection<Books>(_settings.BooksCollectionName);
        }
        public async Task<List<Books>> GetAllAsync()
        {
            return await _book.Find(c => true).ToListAsync();
        }
        public async Task<Books> GetByIdAsync(string id)
        {
            return await _book.Find<Books>(c => c.id == id).FirstOrDefaultAsync();
        }
        public async Task<Books> CreateAsync(Books book)
        {
            await _book.InsertOneAsync(book);
            return book;
        }
        public async Task UpdateAsync(string id, Books book)
        {
            await _book.ReplaceOneAsync(c => c.id == id, book);
        }
        public async Task DeleteAsync(string id)
        {
            await _book.DeleteOneAsync(c => c.id == id);
        }
    }
  • Line #3 – Defining the MongoCollection of Books.
  • Line #4 – Since we are using the IOptions Pattern to read our MongoDB Connection Configuration from the appsetting.json, we will have to inject the configuration class to the constructor.
  • Line #8 – Injecting the IOptions of the Configuration to the constructor.
  • Line #12-13 – Getting the Configuration Information and initializing the Books collection.
  • Line #15-35 – Here we added the CRUD methods.

Add the Dependency Injection inside startup

Add the Dependency Injection inside ConfigureServices class on startup class.

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "CoreAPI.Mongo", Version = "v1" });
            });
            services.Configure<BooksConfiguration>(Configuration.GetSection("BooksConnectionSettings"));
            services.AddScoped<IBookService, BookService>();
        }
  • Line #4-7 – Swagger configuration.
  • Line #8 – Configuration to read the connections.
  • Line #9 – We inject the service class.

Create Books Controller to implement CRUD

public class BookController : ControllerBase
    {
        private readonly IBookService _bookService;
        public BookController(IBookService bookService)
        {
            _bookService = bookService;
        }
        [HttpGet]
        public async Task<IActionResult> GetAll()
        {
            return Ok(await _bookService.GetAllAsync());
        }
        [HttpGet]
        public async Task<IActionResult> Get(string id)
        {
            var book = await _bookService.GetByIdAsync(id);
            if (book == null)
            {
                return NotFound();
            }
            return Ok(book);
        }
        [HttpPost]
        public async Task<IActionResult> Create(Books book)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest();
            }
            await _bookService.CreateAsync(book);
            return Ok(book.id);
        }
        [HttpPut]
        public async Task<IActionResult> Update(string id, Books booksData)
        {
            var book = await _bookService.GetByIdAsync(id);
            if (book == null)
            {
                return NotFound();
            }
            await _bookService.UpdateAsync(id, booksData);
            return NoContent();
        }
        [HttpDelete]
        public async Task<IActionResult> Delete(string id)
        {
            var book = await _bookService.GetByIdAsync(id);
            if (book == null)
            {
                return NotFound();
            }
            await _bookService.DeleteAsync(book.id);
            return NoContent();
        }
    }
  • Line #3-6 – Inject the constructor dependency.

Testing the CRUD using Swagger

Let’s run the application and we should test the application using swagger.

Creating a New Book collection

Let’s create a POST request JSON like below and hit execute button.

And you can see now the new book item has been added into our collection in MongDB database.

Read all book Collection

Get Books by Id

To get a Book by Id, send a GET Request to the same endpoint, but with an additional parameter, the Book id.

Update Books Data

Send the Book id as the parameter of the endpoint and also the Book data to be updated.

And you can see the update data is there.

Delete Book Data

To delete a Books data, simply send in the id as the parameter with DELETE Request like below.

Now, let’s refresh the MongoDB compass and we can see that the book data is removed from the collection.

Find Source Code

Please find the source code in GitHub.

Navigate source code

Summary

In this article, we covered the basic concepts of NOSQL Databases with mongoDB in ASP.NET Core Web API, we discuss here Introduction to MongoDB, Installing MongoDB. We built an ASP.NET Core 5.0 WebAPI that demonstrates the integration of MongoDB in ASP.NET Core seamlessly.

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

Buy me a coffeeBuy me a coffee

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

This article explain how to send Email in ASP.NET Core using Mailkit. It is open-source cross-platform library that can be Read more

CQRS pattern with MediatR in ASP.NET Core 5.0
CQRS pattern with MediatR in ASP.NET Core 5.0

This article explain CQRS design pattern with MediatR in ASP.Net Core 5.0. CQRS is a design pattern that separated the 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

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

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

Pin It on Pinterest