CRUD Operation in ASP.NET MVC

Alifiyakapasi
5 min readSep 2, 2024

--

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:

Final output of CRUD Operation
Create Page View with Validation
Edit View Page

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.

Happy Coding!

--

--

No responses yet