In this ASP.NET Core 2.0 Tutorial, we will follow a step by step approach and create an application performing all CRUD (Create, Retrieve, Update, Delete) operations with MongoDB. In order to keep things simple and we are using “Product” entity to perform all CRUD operations.
Pre-Requisites:
Below are the Prerequisites for understanding and executing the ASP.NET MVC Core 2.0 application.
Below steps guide you to creating a new project.
Now, in this ASP.NET Core 2.0 article, we will move forward to create an Entity i.e. Product, it’s snapshot, Listing page, Creation page, Editing page and Deleting a record.
using MongoDB.Bson.Serialization.Attributes; using System.ComponentModel.DataAnnotations; namespace DotNetCoreWithMongoApplication.Model { public class Product { [BsonId] public string Id { get; set; } [Display(Name = "Product Name")] public string Name { get; set; } [Display(Name = "Product Code")] public string Code { get; set; } [Display(Name = "Product Category")] public string ProductCategory { get; set; } } }
namespace DotNetCoreWithMongoApplication.Model { public class MongoSetting { public string ConnectionString; public string Database; } }
using DotNetCoreWithMongoApplication.Model; using Microsoft.Extensions.Options; using MongoDB.Driver; namespace DotNetCoreWithMongoApplication.Data { public class ProductContext { private readonly IMongoDatabase _database = null; public ProductContext(IOptions<MongoSetting> settings) { var client = new MongoClient(settings.Value.ConnectionString); if (client != null) _database = client.GetDatabase(settings.Value.Database); } public IMongoCollection<Product> Products { get { return _database.GetCollection<Product>("Product"); } } } }
using DotNetCoreWithMongoApplication.Model; using System.Collections.Generic; using System.Threading.Tasks; namespace DotNetCoreWithMongoApplication.Interface { public interface IProductRepository { Task<IEnumerable<Product>> GetAllProducts(); Task<Product> GetProduct(string id); Task AddProduct(Product item); Task<bool> RemoveProduct(string id); Task<bool> UpdateProduct(string id, Product item); } }
You can easily find the IProductRepository implementation with available source code.
using DotNetCoreWithMongoApplication.Data; using DotNetCoreWithMongoApplication.Interface; using DotNetCoreWithMongoApplication.Model; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace DotNetCoreWithMongoApplication { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); services.AddMvc(); services.Configure<MongoSetting>(options => { options.ConnectionString = Configuration.GetSection("MongoConnection:ConnectionString").Value; options.Database = Configuration.GetSection("MongoConnection:Database").Value; }); services.AddTransient<IProductRepository, ProductRepository>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseCors("CorsPolicy"); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Product}/{action=Index}/{id?}"); }); } } }
In this section, we can define the View, Controller logic, Repository logic and output screen for Product List page.
@model IEnumerable<DotNetCoreWithMongoApplication.Model.Product> @using DotNetCoreWithMongoApplication.Model <div class="top-buffer"></div> <div class="panel panel-primary"> <div class="panel-heading panel-head">Products</div> <div class="panel-body"> <div class="btn-group"> <a id="createEditProductModal" data-toggle="modal" asp-action="AddEditProduct" data-target="#modal-action-product" class="btn btn-primary"> <i class="glyphicon glyphicon-plus"></i> Add Product </a> </div> <div class="top-buffer"></div> <table class="table table-bordered table-striped table-condensed"> <thead> <tr> <th>Name</th> <th>Code</th> <th>Product Category</th> <th>Action</th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@Html.DisplayFor(modelItem => item.Name)</td> <td>@Html.DisplayFor(modelItem => item.Code)</td> <td>@Html.DisplayFor(modelItem => item.ProductCategory)</td> <td> <a id="editProductModal" data-toggle="modal" asp-action="AddEditProduct" asp-route-id= "@item.Id" data-target="#modal-action-product" class="btn btn-info"> <i class="glyphicon glyphicon-pencil"></i> Edit </a> <a id="deleteProductModal" data-toggle="modal" asp-action="DeleteProduct" asp-route-id= "@item.Id" data-target="#modal-action-product" class="btn btn-danger"> <i class="glyphicon glyphicon-trash"></i> Delete </a> </td> </tr> } </tbody> </table> </div> </div> @Html.Partial("_Modal", new BootstrapModel { ID = "modal-action-product", AreaLabeledId = "modal-action-product-label", Size = ModalSize.Medium }) @section scripts { <script src="~/js/product-index.js" asp-append-version="true"></script> }
[HttpGet] public IActionResult Index() { IEnumerable<Product> model = _productRepository.GetAllProducts().Result; return View("Index", model); }
public async Task<IEnumerable<Product>> GetAllProducts() { try { return await _context.Products.Find(_ => true).ToListAsync(); } catch (Exception ex) { throw ex; } }
In this section, we can define the View, Controller logic, Repository logic and output screen for Add/Edit product.
@model DotNetCoreWithMongoApplication.Model.Product @using DotNetCoreWithMongoApplication.Model <form asp-action="AddEditProduct" role="form"> @await Html.PartialAsync("_ModalHeader", new ModalHeader { Heading = String.Format("{0} Product", string.IsNullOrWhiteSpace(Model.Id) ? "Add" : "Edit") }) <div class="modal-body form-horizontal"> <div class="form-group"> <label asp-for="Name" class="col-lg-3 col-sm-3 control-label"></label> <div class="col-lg-6"> <input asp-for="Name" class="form-control" /> </div> </div> <div class="form-group"> <label asp-for="Code" class="col-lg-3 col-sm-3 control-label"></label> <div class="col-lg-6"> <input asp-for="Code" class="form-control" /> </div> </div> <div class="form-group"> <label asp-for="ProductCategory" class="col-lg-3 col-sm-3 control-label"></label> <div class="col-lg-6"> <input asp-for="ProductCategory" class="form-control" /> </div> </div> </div> @await Html.PartialAsync("_ModalFooter", new ModalFooter { }) </form>
[HttpGet] public IActionResult AddEditProduct(string id) { Product model = new Product(); if (!string.IsNullOrWhiteSpace(id)) { model = _productRepository.GetProduct(id).Result; } return PartialView("~/Views/Product/_AddEditProduct.cshtml", model); } [HttpPost] public ActionResult AddEditProduct(string id, Product model) { try { if (ModelState.IsValid) { bool isNew = string.IsNullOrWhiteSpace(id); if (isNew) { model.Id = ObjectId.GenerateNewId().ToString(); _productRepository.AddProduct(model); } else { _productRepository.UpdateProduct(id, model); } } } catch (Exception ex) { throw ex; } return RedirectToAction("Index"); }
public async Task AddProduct(Product item) { try { await _context.Products.InsertOneAsync(item); } catch (Exception ex) { throw ex; } }
public async Task<bool> UpdateProduct(string id, Product item) { try { ReplaceOneResult actionResult = await _context.Products .ReplaceOneAsync(n => n.Id.Equals(id) , item , new UpdateOptions { IsUpsert = true }); return actionResult.IsAcknowledged && actionResult.ModifiedCount > 0; } catch (Exception ex) { throw ex; } }
In this section, we can define the View, Controller logic, Repository logic and output screen for Delete product.
@model DotNetCoreWithMongoApplication.Model.Product @using DotNetCoreWithMongoApplication.Model @using (Html.BeginForm()) { @Html.Partial("_ModalHeader", new ModalHeader { Heading = "Delete Product" }) <div class="modal-body form-horizontal"> Are you want to delete @Model.Name? </div> @Html.Partial("_ModalFooter", new ModalFooter { SubmitButtonText = "Delete" }) }
[HttpGet] public IActionResult DeleteProduct(string id) { Product product = _productRepository.GetProduct(id).Result; return PartialView("~/Views/Product/_DeleteProduct.cshtml", product); } [HttpPost] public IActionResult DeleteProduct(string id, IFormCollection form) { _productRepository.RemoveProduct(id); return RedirectToAction("Index"); }
public async Task<Product> GetProduct(string id) { var filter = Builders<Product>.Filter.Eq("Id", id); try { return await _context.Products .Find(filter) .FirstOrDefaultAsync(); } catch (Exception ex) { throw ex; } } public async Task<bool> RemoveProduct(string id) { try { DeleteResult actionResult = await _context.Products.DeleteOneAsync( Builders<Product>.Filter.Eq("Id", id)); return actionResult.IsAcknowledged && actionResult.DeletedCount > 0; } catch (Exception ex) { throw ex; } }
Concluding Remarks: We have created an ASP.NET Core 2.0 application with all CRUD operations following a step by step approach. This simple application can be taken as base to further enhance your skills and develop more advanced applications on ASP.NET Core 2.0.
Choosing the right career path can be a daunting task, especially with the myriad of…
Believe it or not, the concept of human resources has existed for more than 100…
Web3 managed to change the gaming industry by leveraging blockchain technology. It offers a decentralized…
College is often fun and is filled with lots of activities, especially in the first…
The internet has evolved significantly, from static Web1 pages to the dynamic, user-driven Web2 we…
Disaster recovery (DR) is the process which an organization can recover and keep working after…