CRUD Operation in ASP.NET MVC
This article will guide readers through each step of the CRUD (Create, Read, Update, Delete) process in MVC.
Prerequisites
- ASP.NET MVC project: Make sure you have an setup ASP.NET MVC project.
- MongoDB: Install MongoDB and ensure it’s running. Also, install the MongoDB driver for .NET.
- NuGet Packages: The.NET MongoDB driver is required.
You can install the MongoDB driver using NuGet Package Manager:
In the Program Manager Console, type this command.
Install-Package MongoDB.Driver
1. Create MongoDB Context
To control the MongoDB connection and database activities, create a class.
MongoDBContext.cs
using MongoDB.Driver;
namespace DEMO
{
public class MongoDBContext
{
private readonly IMongoDatabase _database;
public MongoDBContext(string databaseName)
{
var client = new MongoClient("mongodb://localhost:27017"); // Local Connection string
_database = client.GetDatabase(databaseName);
}
public IMongoCollection<UserModel> UserCollection =>
_database.GetCollection<UserModel>("UserCollection");
}
}
2. Create the Model
Describe the model class that represents the data structure’s representation.
UserModel.cs
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson;
namespace DEMO.Models
{
public class UserModel
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Email is required")]
public string? Email { get; set; }
public bool IsDeleted { get; set; }
}
}
3. Create the Controller
To manage HTTP requests, construct an MVC controller.
UserController.cs
using DEMO.Models;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
namespace DEMO.Controllers
{
public class UserController : Controller
{
private readonly IMongoCollection<UserModel> _collection;
public UserController(MongoDBContext context)
{
_collection = context.UserCollection;
}
// GET: User
public async Task<ActionResult> Index()
{
var models = await _collection.Find(x => !x.IsDeleted).ToListAsync();
return View(models);
}
// GET: User/Create
public ActionResult Create()
{
return View();
}
// POST: User/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(UserModel model)
{
if (ModelState.IsValid)
{
await _collection.InsertOneAsync(model);
return RedirectToAction("Index");
}
return View(model);
}
// GET: User/Edit/id
public async Task<ActionResult> Edit(string id)
{
var model = await _collection.Find(x => x.Id == id).FirstOrDefaultAsync();
return View(model);
}
// POST: User/Edit/id
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(string id, UserModel model)
{
if (ModelState.IsValid)
{
await _collection.ReplaceOneAsync(x => x.Id == id, model);
return RedirectToAction("Index");
}
return View(model);
}
// GET: User/Delete/id
public async Task<ActionResult> Delete(string id)
{
var model = await _collection.Find(x => x.Id == id).FirstOrDefaultAsync();
// If we wish to remove something permanently, we can use MongoDB's Delete Method.
// await _collection.DeleteOneAsync(x => x.Id == id);
// However, it is best practice to set the flag for IsDeleted instead.
var update = Builders<UserModel>.Update.Set(x => x.IsDeleted, true);
var result = await _collection.UpdateOneAsync(x => x.Id == id, update);
return RedirectToAction("Index");
}
}
}
4. Create Views
In order to communicate with the user, create the views. For the Index, Create and Edit views, these are some simple examples.
Views/User/Index.cshtml
@model IEnumerable<UserModel>
@{
ViewBag.Title = "Index";
}
<div class="container">
<div class="d-flex justify-content-between">
<h2>@ViewBag.Title</h2>
<span>
@Html.ActionLink("Create New", "Create", new { @class = "btn btn-primary btn-sm" })
</span>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Email)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Id }, new { @class = "btn btn-warning btn-sm" }) |
@Html.ActionLink("Delete", "Delete", new { id = item.Id }, new { @class = "btn btn-danger btn-sm" })
</td>
</tr>
}
</tbody>
</table>
</div>
Views/User/Create.cshtml
@model UserModel
@{
ViewBag.Title = "Create";
}
<div class="container">
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm("Create", "User", FormMethod.Post, new { @class = "form-horizontal" }))
{
@Html.AntiForgeryToken()
<div class="form-group">
@Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">Create</button>
</div>
</div>
}
</div>
Views/User/Edit.cshtml
@model UserModel
@{
ViewBag.Title = "Edit";
}
<div class="container">
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm("Edit", "User", FormMethod.Post, new { @class = "form-horizontal" }))
{
@Html.AntiForgeryToken()
<div class="form-group">
@Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })
<div class="col-md-4">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
}
</div>
In Program.cs
/* Write before var app = builder.Build(); */
builder.Services.AddSingleton<MongoDBContext>(provider =>
new MongoDBContext("User"));
Style if you want to add:
site.css(optional)
body {
padding-top: 20px;
padding-bottom: 20px;
}
.table th, .table td {
vertical-align: middle;
}
h2 {
margin-top: 0;
}
.form-horizontal .form-group {
margin-left: 0;
margin-right: 0;
}
.form-group {
margin-bottom: 1rem;
}
.control-label {
text-align: left;
}
In _Layout.cshtml
@* Inside header section *@
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
@* For validation Add scripts, in Script section also maintain this order *@
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
Final Output:
Please leave a comment below if you have any questions about this and let me know what topic you would want to read in future.