DEV Community

Cover image for Step by step guide on how to create an  Asp.Net Core MVC CRUD, Ef Core code first approach
Mohamad Lawand
Mohamad Lawand

Posted on • Updated on

Step by step guide on how to create an Asp.Net Core MVC CRUD, Ef Core code first approach

In this article we will be exploring how to create an Asp.Net Core MVC CRUD, Ef Core code first approach you can watch the full tutorial on Youtube as well

Source code: https://github.com/mohamadlawand087/v4-Phonebook

The 3 things that we will need before we start:

For this sample application we will be using SQLite as our local database. After installing all of requirements, we need to make sure that the dotnet SDK has been installed successfully, we need to open the terminal and check if the dotnet SDK is installed successfully by checking the dotnet version.

Open the terminal type the command below

dotnet --version
Enter fullscreen mode Exit fullscreen mode

Now we need to install the entity framework tool

dotnet tool install --global dotnet-ef
Enter fullscreen mode Exit fullscreen mode

Now we need to create an asp.net core application using the following command

dotnet new mvc -n "Phonebook" -lang "C#" -au none
Enter fullscreen mode Exit fullscreen mode

Now we need to add the required packages to utilise SQLLite and Entity Framework Core

dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet add package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Enter fullscreen mode Exit fullscreen mode

Once we add the packages we need to update the appsettings.json to include the connection string to our database

"ConnectionStrings": {
    "DefaultConnection": "DataSource=app.db;Cache=Shared"
  }
Enter fullscreen mode Exit fullscreen mode

We open visual studio code, we need to open the terminal from within visual studio code.You can go to Views ⇒ Terminal. Now we need to make sure that the application is building by running the code below

dotnet build
dotnet run
Enter fullscreen mode Exit fullscreen mode

Once we make sure that the application is running we will start by creating our ApplicationDbContext. We need to create a Data folder in he root directory, and then will create the ApplicationDbContext class

using Microsoft.EntityFrameworkCore;

namespace Phonebook.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Once we add our ApplicationDbContext we need to update the startup class to utilise the DbContext

services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlite(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddDatabaseDeveloperPageExceptionFilter();
Enter fullscreen mode Exit fullscreen mode

Once we have add the DbContext middleware we need to add the initial migration to create the database.

dotnet ef migrations add "Initial Migrations"
dotnet ef database update
Enter fullscreen mode Exit fullscreen mode

lets now check our solution and see if we have the database file create, we can now see the database is there.

So our next step is to create our Model, we will call it Contact.

Inside the model folder create a new C# class and call it Contact, inside the Contact class we will define 5 properties "Id", "First Name", "Last Name", "Email", "Mobile".

public class Contact
{
      public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Mobile { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Now we need to add our Model to the application DbContext by adding the code below

public class ApplicationDbContext : DbContext
{
        // The DbSet property will tell EF Core tha we have a table that needs to be created
    public virtual DbSet<Contact> Contacts { get; set; }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

        // On model creating function will provide us with the ability to manage the tables properties
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}
Enter fullscreen mode Exit fullscreen mode

Once we update the ApplicationDbContext we need to create a new migration script to prepare the EF Core to update our database

dotnet ef migrations add "Adding the Contact table"
dotnet ef database update 
Enter fullscreen mode Exit fullscreen mode

After the database update is completed, we can check our sqlite db with the SQLite browser, we can see that the table has been created for us.

Now we need to create the controller and create the actions. Right click on the controller folder and add a new class calling it ContactsController and we need to inherit from the controller class

public class ContactsController : Controller
{

}
Enter fullscreen mode Exit fullscreen mode

We need to create and initiate the ApplicationDbContext inside our new Contacts controller and create the action index, and get all of the contacts from the database

public class ContactsController : Controller
{
    private ApplicationDbContext _context;

    public ContactsController(ApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<IActionResult> Index()
    {
        var contacts = await _context.Contacts.ToListAsync();
        return View(contacts);
    }
}
Enter fullscreen mode Exit fullscreen mode

Now we need to create the view folder for the controller, under the views folder we need to create a folder called Contacts.

once we create the folder we need to create a view for the index, within the index we need to create a table which will list all of the contacts that we have.

@model List<Phonebook.Models.Contact>

<div class="row">
    <div class="col-md-12">
        <a asp-action="Create" asp-controller="Contacts" class="btn btn-success">Create</a>
    </div>
</div>
<div class="row">
    <div class="col-md-12">
        <table class="table">
            <thead>
                <tr>
                    <td>First Name</td>
                    <td>Last Name</td>
                    <td>Email</td>
                    <td>Mobile</td>
                    <td>Manage</td>
                </tr>
            </thead>
            <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>@item.FirstName</td>
                    <td>@item.LastName</td>
                    <td>@item.Email</td>
                    <td>@item.Mobile</td>
                    <td>
                        <a asp-action="Edit" asp-controller="Contacts" asp-route-id="@item.Id">
                            Edit
                        </a>
                        <a asp-action="Delete" asp-controller="Contacts" asp-route-id="@item.Id">
                            Delete
                        </a>
                    </td>
                </tr>
            }
            </tbody>
        </table>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Once we create it we need to build and run the application to make sure everything is running as it should be

dotnet build
dotnet run

Enter fullscreen mode Exit fullscreen mode

When we go to the ContactsController we can see there is nothing in our table since we didnt add any record yet which is the correct behaviour, now lets start creating the Create action to add information to our database.

[HttpGet]
public IActionResult Create()
{
    return View();
}

[HttpPost]
public async Task<IActionResult> Create(Contact contact)
{
    // validate that our model meets the requirement
    if (ModelState.IsValid)
    {
        try
        {
            // update the ef core context in memory 
            _context.Add(contact);

            // sync the changes of ef code in memory with the database
            await _context.SaveChangesAsync();

            return RedirectToAction("Index");
        }
        catch(Exception ex)
        {
            ModelState.AddModelError(string.Empty, $"Something went wrong {ex.Message}");
        }
    }

    ModelState.AddModelError(string.Empty, $"Something went wrong, invalid model");

    // We return the object back to view
    return View(contact);
}
Enter fullscreen mode Exit fullscreen mode
@model Phonebook.Models.Contact

<form asp-action="Create" asp-area="Contacts" method="post">
    <div class="row">
        <div class="col-lg-12">
            <div class="form-group">
                <label>First Name:</label>
                <input asp-for="FirstName" type="text" class="form-control required" placeholder="Enter first name" tabindex="1">
            </div>
             <div class="form-group">
                <label>Last Name:</label>
                <input asp-for="LastName" type="text" class="form-control required" placeholder="Enter last name" tabindex="2">
            </div>
             <div class="form-group">
                <label>Email:</label>
                <input asp-for="Email" type="text" class="form-control required" placeholder="Enter email" tabindex="3">
            </div>
             <div class="form-group">
                <label>Mobile:</label>
                <input asp-for="Mobile" type="text" class="form-control required" placeholder="Enter mobile" tabindex="4">
            </div>
            <div class="form-group">
                <div asp-validation-summary="All" class="text-danger"></div>
            </div>
            <div class="card-footer">
                <center>
                    <button type="submit" class="btn btn-primary">Create Contact</button>
                    <a asp-action="Index" asp-controller="Contacts" class="btn btn-secondary">Cancel</a>
                </center>
            </div>
        </div>
    </div>
</form>
Enter fullscreen mode Exit fullscreen mode

Once we create it we need to build and run the application to make sure everything is running as it should be

dotnet build
dotnet run
Enter fullscreen mode Exit fullscreen mode

lets navigate to the create page and add some records we can now see the data is being populated as it should from the database

Alt Text

Now we need to add the edit functionality so we can update our contacts, in order for us to do that we need to add the Edit action as well the Edit View.

[HttpGet]
public async Task<IActionResult> Edit(int id)
{
    var exist = await _context.Contacts.Where(x => x.Id == id).FirstOrDefaultAsync();

    return View(exist);
}

[HttpPost]
public async Task<IActionResult> Edit(Contact contact)
{
    // validate that our model meets the requirement
    if (ModelState.IsValid)
    {
        try
        {
            // Check if the contact exist based on the id
            var exist = _context.Contacts.Where(x => x.Id == contact.Id).FirstOrDefault();

            // if the contact is not null we update the information
            if(exist != null)
            {
                exist.FirstName = contact.FirstName;
                exist.LastName = contact.LastName;
                exist.Mobile = contact.Mobile;
                exist.Email = contact.Email;

                // we save the changes into the db
                await _context.SaveChangesAsync();

                return RedirectToAction("Index");
            }
        }
        catch(Exception ex)
        {
            ModelState.AddModelError(string.Empty, $"Something went wrong {ex.Message}");
        }
    }

    ModelState.AddModelError(string.Empty, $"Something went wrong, invalid model");

    return View(contact);
}
Enter fullscreen mode Exit fullscreen mode
@model Phonebook.Models.Contact

<form asp-action="Edit" asp-area="Contacts" method="post">
    <input type="hidden" asp-for="Id" />
    <div class="row">
        <div class="col-lg-12">
            <div class="form-group">
                <label>First Name:</label>
                <input asp-for="FirstName" type="text" class="form-control required" placeholder="Enter first name" tabindex="1">
            </div>
             <div class="form-group">
                <label>Last Name:</label>
                <input asp-for="LastName" type="text" class="form-control required" placeholder="Enter last name" tabindex="2">
            </div>
             <div class="form-group">
                <label>Email:</label>
                <input asp-for="Email" type="text" class="form-control required" placeholder="Enter email" tabindex="3">
            </div>
             <div class="form-group">
                <label>Mobile:</label>
                <input asp-for="Mobile" type="text" class="form-control required" placeholder="Enter mobile" tabindex="4">
            </div>
            <div class="form-group">
                <div asp-validation-summary="All" class="text-danger"></div>
            </div>
            <div class="card-footer">
                <center>
                    <button type="submit" class="btn btn-warning">Update Contact</button>
                    <a asp-action="Index" asp-controller="Contacts" class="btn btn-secondary">Cancel</a>
                </center>
            </div>
        </div>
    </div>
</form>
Enter fullscreen mode Exit fullscreen mode

lets run the application now and test the functionality

dotnet build
dotnet run
Enter fullscreen mode Exit fullscreen mode

Alt Text

And finally we need to add the Delete action and view to be able to remove contacts

[HttpGet]
public async Task<IActionResult> Delete(int id)
{
    var exist = await _context.Contacts.Where(x => x.Id == id).FirstOrDefaultAsync();

    return View(exist);
}

[HttpPost]
public async Task<IActionResult> Delete(Contact contact)
{
    if (ModelState.IsValid)
    {
        try
        {
            var exist = _context.Contacts.Where(x => x.Id == contact.Id).FirstOrDefault();

            if(exist != null)
            {
                _context.Remove(exist);
                await _context.SaveChangesAsync();

                return RedirectToAction("Index");
            } 
        }
        catch(Exception ex)
        {
            ModelState.AddModelError(string.Empty, $"Something went wrong {ex.Message}");
        }
    }

    ModelState.AddModelError(string.Empty, $"Something went wrong, invalid model");

    return View();
}
Enter fullscreen mode Exit fullscreen mode
@model Phonebook.Models.Contact

<form asp-action="Delete" asp-area="Contacts" method="post">
    <input type="hidden" asp-for="Id" />
    <div class="row">
        <div class="col-lg-12">
            <div class="form-group">
                <label>First Name:</label>
                <input asp-for="FirstName" type="text" disabled class="form-control required" placeholder="Enter first name" tabindex="1">
            </div>
             <div class="form-group">
                <label>Last Name:</label>
                <input asp-for="LastName" type="text" disabled class="form-control required" placeholder="Enter last name" tabindex="2">
            </div>
             <div class="form-group">
                <label>Email:</label>
                <input asp-for="Email" type="text" disabled class="form-control required" placeholder="Enter email" tabindex="3">
            </div>
             <div class="form-group">
                <label>Mobile:</label>
                <input asp-for="Mobile" type="text" disabled class="form-control required" placeholder="Enter mobile" tabindex="4">
            </div>
            <div class="form-group">
                <div asp-validation-summary="All" class="text-danger"></div>
            </div>
            <div class="card-footer">
                <center>
                    <button type="submit" class="btn btn-danger">Delete Contact</button>
                    <a asp-action="Index" asp-controller="Contacts" class="btn btn-secondary">Cancel</a>
                </center>
            </div>
        </div>
    </div>
</form>
Enter fullscreen mode Exit fullscreen mode

now lets run the application now and test the functionality

dotnet build
dotnet run
Enter fullscreen mode Exit fullscreen mode

the last thing we need to do is to add a link to the contacts page in the menu, to do that we need to go to Views ⇒ Shared ⇒ _Layout.cshtml and add the code below

<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-controller="Contacts" asp-action="Index">Contacts</a>
</li>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)