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

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

Worker Service in .NET Core
worker-service

A worker service is a .NET project built using a template which supplies a few useful features that turn a 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": "[email protected]",
    "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

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

Migrate from ASP.NET Core 3.1 to 5.0- Beginners guide
Migrate from ASP.NET Core 3.1 to 5.0

This article explains how to update an existing ASP.NET Core 3.1 project to ASP.NET Core 5.0. Also we learn how Read more

Pin It on Pinterest