Create A Free MongoDB Atlas Cluster And Connect With MVC

In this article, we will create a free MongoDB Atlas cluster and connect this cluster with an MVC 5 application.

Introduction

 
In my last article, we saw how to create a multi-node cluster in windows local machine using a replica set. In this article, we will see how to create a free MongoDB Atlas cluster. MongoDB Atlas is a fully-managed cloud database. Atlas handles all the complexity of deploying, managing, and healing your deployments on the cloud service provider of your choice (Azure, AWS, and GCP).
 
Currently, MongoDB Atlas provides 512 MB free space. We will see all the steps to create a free MongoDB cluster in this tutorial.

Open this link to create a new cluster.

 

Give your email address and full name and give a strong password and then click “Get started free” button.

We can choose the appropriate cloud provider from the below list. I am choosing Azure as a cloud provider. Each provider has its own regions.

 
 
Please note that free tier is available in limited regions only.
 
I have chosen “Hong Kong” as my region. We can choose the appropriate price tier now.
 
 
We have chosen the free tier with 512 MB storage plan. We can give a cluster name as well.
 
We can click “Create Cluster” button to create the free cluster now.
 
 
 
Please note, it will take from 7 to 10 minutes to complete the entire cluster provisioning.
 
 
 
We can create a new database user now. Click “Security” tab and click “ADD NEW USER” button.
 
 

I have selected “Atlas admin” role for our user so that all the admin privileges will be given to the user.

We can add IP address to the IP Whitelists. Please choose “IP Whitelist” tab and click “ADD IP ADDRESS” button.

 

For testing purposes, I have allowed the access from anywhere option. Please note, production databases do not allow all IP addresses for security reasons.

Our MongoDB Atlas cluster is ready to use now. We can click the “Connect” button to get the connection string details.
 
 

There are various options available to connect with MongoDB cluster. We can choose the “Connect Your Application” option as we are going to connect with our MVC 5 application.

We can select C#/NET driver and version 2.5 or later.
 
 

Please copy the connection string and save to a safe place. We will use this connection string later with our MVC 5 application.

Create MVC 5 Application

 
We can create the MVC application now. Please choose the MVC template from Visual Studio.
 
 
We can install the “MongoDB.Driver” NuGet package to our project.
 

We are creating a sample Employee data management application. So, we can create an “Employee” class inside the “Models” folder. Please copy the below code and paste in Employee class.

Employee.cs
  1. using MongoDB.Bson;  
  2. using MongoDB.Bson.Serialization.Attributes;  
  3.   
  4. namespace MongoDBMVC.Models  
  5. {  
  6.     public class Employee  
  7.     {  
  8.         [BsonId]  
  9.         [BsonRepresentation(BsonType.ObjectId)]  
  10.         public string Id { getset; }  
  11.         public string Name { getset; }  
  12.         public string Address { getset; }  
  13.         public string Gender { getset; }  
  14.         public string Company { getset; }  
  15.         public string Designation { getset; }  
  16.     }  
  17. }  

We can create a “MongoDbContext” context class and give the MongoDB connection details inside this class.

MongoDbContext.cs
  1. using MongoDB.Driver;  
  2.   
  3. namespace MongoDBMVC.Models  
  4. {  
  5.     public class MongoDbContext  
  6.     {  
  7.         private readonly IMongoDatabase _mongoDb;  
  8.         public MongoDbContext()  
  9.         {  
  10.             var client = new MongoClient("mongodb+srv://sarathlal:<password>@sarathlal-6k9bj.azure.mongodb.net?retryWrites=true");  
  11.             _mongoDb = client.GetDatabase("SarathDB");  
  12.         }  
  13.         public IMongoCollection<Employee> Employee  
  14.         {  
  15.             get  
  16.             {  
  17.                 return _mongoDb.GetCollection<Employee>("Employee");  
  18.             }  
  19.         }  
  20.     }  
  21. }  

We have given MongoDB database name and collection name (Employee) inside above class. MongoDB driver will automatically create a database and collection in the first run.

We can create a “IEmployeeRepository” interface and add some members inside it.

IEmployeeRepository.cs
  1. using System.Collections.Generic;  
  2. using System.Threading.Tasks;  
  3.   
  4. namespace MongoDBMVC.Models  
  5. {  
  6.     public interface IEmployeeRepository  
  7.     {  
  8.         Task Add(Employee employee);  
  9.         Task Update(Employee employee);  
  10.         Task Delete(string id);  
  11.         Task<Employee> GetEmployee(string id);  
  12.         Task<IEnumerable<Employee>> GetEmployees();  
  13.     }  
  14. }  

We can implement “IEmployeeRepository” interface inside a new class “EmployeeRepository”

EmployeeRepository.cs
  1. using MongoDB.Driver;  
  2. using System.Collections.Generic;  
  3. using System.Threading.Tasks;  
  4.   
  5. namespace MongoDBMVC.Models  
  6. {  
  7.     public class EmployeeRepository : IEmployeeRepository  
  8.     {  
  9.         MongoDbContext db = new MongoDbContext();  
  10.         public async Task Add(Employee employee)  
  11.         {  
  12.             try  
  13.             {  
  14.                 await db.Employee.InsertOneAsync(employee);  
  15.             }  
  16.             catch  
  17.             {  
  18.                 throw;  
  19.             }  
  20.         }  
  21.         public async Task<Employee> GetEmployee(string id)  
  22.         {  
  23.             try  
  24.             {  
  25.                 FilterDefinition<Employee> filter = Builders<Employee>.Filter.Eq("Id", id);  
  26.                 return await db.Employee.Find(filter).FirstOrDefaultAsync();  
  27.             }  
  28.             catch  
  29.             {  
  30.                 throw;  
  31.             }  
  32.         }  
  33.         public async Task<IEnumerable<Employee>> GetEmployees()  
  34.         {  
  35.             try  
  36.             {  
  37.                 return await db.Employee.Find(_ => true).ToListAsync();  
  38.             }  
  39.             catch  
  40.             {  
  41.                 throw;  
  42.             }  
  43.         }  
  44.         public async Task Update(Employee employee)  
  45.         {  
  46.             try  
  47.             {  
  48.                 await db.Employee.ReplaceOneAsync(filter: g => g.Id == employee.Id, replacement: employee);  
  49.             }  
  50.             catch  
  51.             {  
  52.                 throw;  
  53.             }  
  54.         }  
  55.         public async Task Delete(string id)  
  56.         {  
  57.             try  
  58.             {  
  59.                 FilterDefinition<Employee> data = Builders<Employee>.Filter.Eq("Id", id);  
  60.                 await db.Employee.DeleteOneAsync(data);  
  61.             }  
  62.             catch  
  63.             {  
  64.                 throw;  
  65.             }  
  66.         }  
  67.     }  
  68. }  

We have added all the CRUD operations inside the above class.

We can create a new Employee Controller now. We will use the default scaffolding option provided by the MVC template, so that we can automatically create all the views for CRUD operations easily.

We can right click “Controller” folder and click “Add” and choose “New Scaffolded Item” to create a new controller class.
 

Please note, we are opting for Entity framework. We choose this option only to create default views for CRUD operations. We will not use the Entity Framework model in this project as we are connecting with MongoDB.

 

We can choose the “Employee” class as a model and create a new data context class. Please note, we will delete this data context class later. We only choose this option to create default views for CRUD operations as explained earlier.

 

After a few moments, our new controller and corresponding views for CRUD operations will be created successfully.

We can replace the “EmployeesController” class with the below code.
 
EmployeesController.cs
  1. using MongoDBMVC.Models;  
  2. using System.Collections.Generic;  
  3. using System.Net;  
  4. using System.Threading.Tasks;  
  5. using System.Web.Mvc;  
  6.   
  7. namespace MongoDBMVC.Controllers  
  8. {  
  9.     public class EmployeesController : Controller  
  10.     {  
  11.         private readonly IEmployeeRepository _dataAccessProvider = new EmployeeRepository();  
  12.         public async Task<ActionResult> Index()  
  13.         {  
  14.             IEnumerable<Employee> employees = await _dataAccessProvider.GetEmployees();  
  15.             return View(employees);  
  16.         }  
  17.   
  18.         public async Task<ActionResult> Details(string id)  
  19.         {  
  20.             if (id == null)  
  21.             {  
  22.                 return new HttpStatusCodeResult(HttpStatusCode.BadRequest);  
  23.             }  
  24.             Employee employee = await _dataAccessProvider.GetEmployee(id);  
  25.             if (employee == null)  
  26.             {  
  27.                 return HttpNotFound();  
  28.             }  
  29.             return View(employee);  
  30.         }  
  31.   
  32.         public ActionResult Create()  
  33.         {  
  34.             return View();  
  35.         }  
  36.   
  37.         [HttpPost]  
  38.         [ValidateAntiForgeryToken]  
  39.         public async Task<ActionResult> Create([Bind(Include = "Name,Address,Gender,Company,Designation")] Employee employee)  
  40.         {  
  41.             if (ModelState.IsValid)  
  42.             {  
  43.                 await _dataAccessProvider.Add(employee);  
  44.                 return RedirectToAction("Index");  
  45.             }  
  46.   
  47.             return View(employee);  
  48.         }  
  49.   
  50.         public async Task<ActionResult> Edit(string id)  
  51.         {  
  52.             if (id == null)  
  53.             {  
  54.                 return new HttpStatusCodeResult(HttpStatusCode.BadRequest);  
  55.             }  
  56.             Employee employee = await _dataAccessProvider.GetEmployee(id);  
  57.             if (employee == null)  
  58.             {  
  59.                 return HttpNotFound();  
  60.             }  
  61.             return View(employee);  
  62.         }  
  63.   
  64.         [HttpPost]  
  65.         [ValidateAntiForgeryToken]  
  66.         public async Task<ActionResult> Edit([Bind(Include = "Id,Name,Address,Gender,Company,Designation")] Employee employee)  
  67.         {  
  68.             if (ModelState.IsValid)  
  69.             {  
  70.                 await _dataAccessProvider.Update(employee);  
  71.                 return RedirectToAction("Index");  
  72.             }  
  73.             return View(employee);  
  74.         }  
  75.   
  76.         public async Task<ActionResult> Delete(string id)  
  77.         {  
  78.             if (id == null)  
  79.             {  
  80.                 return new HttpStatusCodeResult(HttpStatusCode.BadRequest);  
  81.             }  
  82.   
  83.             Employee employee = await _dataAccessProvider.GetEmployee(id);  
  84.             if (employee == null)  
  85.             {  
  86.                 return HttpNotFound();  
  87.             }  
  88.             return View(employee);  
  89.         }  
  90.   
  91.         [HttpPost, ActionName("Delete")]  
  92.         [ValidateAntiForgeryToken]  
  93.         public async Task<ActionResult> DeleteConfirmed(string id)  
  94.         {  
  95.             await _dataAccessProvider.Delete(id);  
  96.             return RedirectToAction("Index");  
  97.         }  
  98.   
  99.         protected override void Dispose(bool disposing)  
  100.         {  
  101.             base.Dispose(disposing);  
  102.         }  
  103.     }  
  104. }  

We can modify the “Create.cshtml” code with the below code. (We have removed the Id column from this view)

Create.cshtml
  1. @model MongoDBMVC.Models.Employee  
  2.   
  3. @{  
  4.     ViewBag.Title = "Create";  
  5. }  
  6.   
  7. <h2>Create</h2>  
  8.   
  9.   
  10. @using (Html.BeginForm())   
  11. {  
  12.     @Html.AntiForgeryToken()  
  13.       
  14.     <div class="form-horizontal">  
  15.         <h4>Employee</h4>  
  16.         <hr />  
  17.   
  18.         <div class="form-group">  
  19.             @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })  
  20.             <div class="col-md-10">  
  21.                 @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })  
  22.                 @Html.ValidationMessageFor(model => model.Name, ""new { @class = "text-danger" })  
  23.             </div>  
  24.         </div>  
  25.   
  26.         <div class="form-group">  
  27.             @Html.LabelFor(model => model.Address, htmlAttributes: new { @class = "control-label col-md-2" })  
  28.             <div class="col-md-10">  
  29.                 @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control" } })  
  30.                 @Html.ValidationMessageFor(model => model.Address, ""new { @class = "text-danger" })  
  31.             </div>  
  32.         </div>  
  33.   
  34.         <div class="form-group">  
  35.             @Html.LabelFor(model => model.Gender, htmlAttributes: new { @class = "control-label col-md-2" })  
  36.             <div class="col-md-10">  
  37.                 @Html.EditorFor(model => model.Gender, new { htmlAttributes = new { @class = "form-control" } })  
  38.                 @Html.ValidationMessageFor(model => model.Gender, ""new { @class = "text-danger" })  
  39.             </div>  
  40.         </div>  
  41.   
  42.         <div class="form-group">  
  43.             @Html.LabelFor(model => model.Company, htmlAttributes: new { @class = "control-label col-md-2" })  
  44.             <div class="col-md-10">  
  45.                 @Html.EditorFor(model => model.Company, new { htmlAttributes = new { @class = "form-control" } })  
  46.                 @Html.ValidationMessageFor(model => model.Company, ""new { @class = "text-danger" })  
  47.             </div>  
  48.         </div>  
  49.   
  50.         <div class="form-group">  
  51.             @Html.LabelFor(model => model.Designation, htmlAttributes: new { @class = "control-label col-md-2" })  
  52.             <div class="col-md-10">  
  53.                 @Html.EditorFor(model => model.Designation, new { htmlAttributes = new { @class = "form-control" } })  
  54.                 @Html.ValidationMessageFor(model => model.Designation, ""new { @class = "text-danger" })  
  55.             </div>  
  56.         </div>  
  57.   
  58.         <div class="form-group">  
  59.             <div class="col-md-offset-2 col-md-10">  
  60.                 <input type="submit" value="Create" class="btn btn-default" />  
  61.             </div>  
  62.         </div>  
  63.     </div>  
  64. }  
  65.   
  66. <div>  
  67.     @Html.ActionLink("Back to List""Index")  
  68. </div>  
  69.   
  70. @section Scripts {  
  71.     @Scripts.Render("~/bundles/jqueryval")  
  72. }  

We must modify the “_Layout.cshtml” view inside the shared folder with below code.

_Layout.cshtml
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8" />  
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  6.     <title>@ViewBag.Title - My ASP.NET Application</title>  
  7.     @Styles.Render("~/Content/css")  
  8.     @Scripts.Render("~/bundles/modernizr")  
  9. </head>  
  10. <body>  
  11.     <div class="navbar navbar-inverse navbar-fixed-top">  
  12.         <div class="container">  
  13.             <div class="navbar-header">  
  14.                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">  
  15.                     <span class="icon-bar"></span>  
  16.                     <span class="icon-bar"></span>  
  17.                     <span class="icon-bar"></span>  
  18.                 </button>  
  19.                 @Html.ActionLink("MongoDB Atlas With MVC""Index""Home"new { area = "" }, new { @class = "navbar-brand" })  
  20.             </div>  
  21.             <div class="navbar-collapse collapse">  
  22.                 <ul class="nav navbar-nav">  
  23.                     <li>@Html.ActionLink("Home""Index""Home")</li>  
  24.                     <li>@Html.ActionLink("Employee Details""Index""Employees")</li>  
  25.                     <li>@Html.ActionLink("About""About""Home")</li>  
  26.                     <li>@Html.ActionLink("Contact""Contact""Home")</li>  
  27.                 </ul>  
  28.             </div>  
  29.         </div>  
  30.     </div>  
  31.     <div class="container body-content">  
  32.         @RenderBody()  
  33.         <hr />  
  34.         <footer>  
  35.             <p>© @DateTime.Now.Year - My ASP.NET Application</p>  
  36.         </footer>  
  37.     </div>  
  38.   
  39.     @Scripts.Render("~/bundles/jquery")  
  40.     @Scripts.Render("~/bundles/bootstrap")  
  41.     @RenderSection("scripts", required: false)  
  42. </body>  
  43. </html>  

We have completed all the coding part. We can run the application now.

 

You can click the “Employee Details” tab to open the employee menu. You can click the “Create New” button to add new employee details.

 

Conclusion

 
In this article, we have seen how to create a MongoDB Atlas free cluster and connect with an MVC 5 application. We have created a sample Employee application in MVC and added all CRUD operations in it.