Creating a Basic CRUD App with .NET MVC & EF
Tags: beginners, tutorial, github, dotnet
Published: 2022-10-31 21:14:44

I created a basic CRUD App to get started with .NET MVC and Entity Framework.

The app is a Movie Ranker Table that displays Movies and Movie Details ordered by score.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/338ng6qbygyhjgimvdeh.jpg)

You can add new entries to the table, edit existing entries and delete them.


![Add Movie Records](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yndm9lo1rpm535dyh8z7.jpg)

![Edit Movie Records](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmfo6vn170wq87tnv943.jpg)

![Delete Movie Records](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7x58jct2ucy1n4znd99x.jpg)

To get the full code you must clone the repository:

[Here's how to do it](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository)

The repository in question is as follows:

{% github tigerbluejay/MVC-EF-Movie-Ranker-App %}

There in the project description you will find a lengthy list of features.

At its most basic, I needed to create a connection string in appsettings.json

```csharp
// connection string in appsettings.json

"ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=MovieRanker;Trusted_Connection=True;"
  }

```

Then a database context.

```csharp
// Application DbContext Class in Data Folder ApplicationDbContext.cs

using Microsoft.EntityFrameworkCore;
using MVCMovieRanker.Models;

namespace MVCMovieRanker.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {

        }

        public DbSet<Movie> Movies { get; set; }
    }

}

```

And then pass the connection object with details in Program.cs

```csharp
// connection set up in program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
// Register ApplicationDbContext
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(
// Register the connection string in appsettings.json
    builder.Configuration.GetConnectionString("DefaultConnection")
    ));

;
var app = builder.Build();

```
Then I needed to do EF migrations to create the tables in the database based on the model. And then add some dummy data to visualize.

The model I created is as follows:

```csharp
namespace MVCMovieRanker.Models
{
    [Table("Movies")]
    public class Movie
    {
        [Key]
        public int MovieId { get; set; }
        [Required]
        [MaxLength(100)]
        [Column("MovieName")]
        public string Name { get; set; }
        public string? Genre { get; set; }
        [DataType(DataType.Date)]
        [DisplayName("Release Date")]
        //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
        public DateTime ReleaseDate { get; set; }
        public string? Studio { get; set; }
        [Required]
        public int Score { get; set; }
    }
}

```

Then I created a Movie Controller (full code with Create, Edit and Delete Actions in the repo), here showing the implementation of the Index View only which ranks the movies every time it loads.

```csharp
// Controller
  public class MovieController : Controller
    {
        private readonly ApplicationDbContext _db;

        public MovieController(ApplicationDbContext db)
        {
            _db = db;
        }

        public IActionResult Index()
        {
            IEnumerable<Movie> objMovieList = _db.Movies;
            var objMovieListSorted = from objMovie in objMovieList
                                 orderby objMovie.Score descending
                                 select objMovie;
            
            //return View(objMovieList);
            return View(objMovieListSorted);
        }
...
```

And for each Action a View or a redirect to view. Here's what the Movie Index Action looks like:

```html
// View

@model IEnumerable<Movie>

@{
    ViewData["Title"] = "Index";
}

<partial name="_Notification" />


<div class="container p-3">
    <div class="row pt-4">
        <div class="col-6">
            <h2 class="text-primary">Movie List</h2>
        </div>
        <div class="col-6 text-end">
            <a asp-controller="Movie" asp-action="Create" class="btn btn-primary">
                <i class="bi bi-plus-circle"></i> &nbsp; Add New Movie 
            </a>
        </div>
    </div>
    <br /><br />

<table class="table tabled-bordered table-striped" style="width: 100%">
    <thead>
        <tr>
            <th width="20%">
                Movie Name
            </th>
            <th>
                Genre
            </th>
            <th>
                Release Date
            </th>
            <th>
                Studio
            </th>
            <th>
                Score
           </th>
           <th>
                    
           </th>
        </tr>
    </thead>
    <tbody>
        @foreach(var obj in Model)
        {
            <tr>
                <td width="20%">
                    @obj.Name
                </td>
                <td width="15%">
                    @obj.Genre
                </td>
                <td width="15%">
                    @obj.ReleaseDate.ToShortDateString()
                </td>
                <td width="15%">
                    @obj.Studio
                </td>
                <td width="15%">
                    @obj.Score
                </td>
                <td>
                    <div class="w-50 btn-group d-inline" role="group">
                            <a asp-controller="Movie" asp-action="Edit" asp-route-id="@obj.MovieId"
                            class="btn btn-primary mx-2"> 
                                <i class="bi bi-pencil-square"></i>Edit</a>
                    </div>
                    <div class="w-50 btn-group d-inline" role="group">
                            <a asp-controller="Movie" asp-action="Delete" asp-route-id="@obj.MovieId"
                            class="btn btn-danger mx-2">
                                <i class="bi bi-trash-fill"></i>Delete </a>
                    </div>
                </td>
            </tr>
        }
    </tbody>
</table>
</div>
```


The best way to work through this project is to follow through with a list of tasks in mind. 

- To note, on the backend, you should start with the creation of the model, returning to it to add data annotations as needed so you can perform data visualization and validation.
- After creating the model, you should download relevant packages like Entity Framework Core, Entity Framework Core SQL Server, and Entity Framework Core Tools.

You should then proceed with connecting the Model to the database via entity framework: 
1) Define your connection string in appsettings.json 
2) Create an ApplicationDbContext class 
3) Add scripts to the builder in Program.cs to ensure connection to the database 
4) Use Entity Framework's add-migration and update-database commands to create the Model code first into the database
5) Create dummy data in your database to visualize and test CRUD operations 

Apart from having an Index action (for an index view) where you should perform a LINQ query to order records, you should have actions for the other views Create, Edit and Delete (both GET and POST versions).

- On these actions you'll perform some server-side validations with ModelState.IsValid, with the help of Data Annotations in the Model, as well as Add, Update and Remove records. 
- Here you'll also fetch the model's data by id, as well as pass model objects to views.

You can find the code for all of these steps in the MovieController.

The Views (one view per action roughly) will display model data or help the user populate it with extensive use of Tag Helpers. 

On the frontend you'll also resort to Bootstrap and Bootswatch for css and js files which can be refrenced in the _Layout master page or in a partial view. 

Partial views can also be used to provide frontend validations with jquery validation scripts. 

You'll also add javascript scripts for managing alerts with Tostr.js using TempData.

Keeping all of this in mind, you can now jump into the code and explore the full implementation.

Enjoy!

{% user josemariairiarte %}