MVC Code example
This is my controller. I think of a controller as the quarterback. He controls everything. This particular controller has 3 action methods, Add(), Edit() and Delete(). Also, both Edit() and Delete() actions have overloads for GET and POST requests.
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using MovieList.Models;
namespace MovieList.Controllers
{
public class MovieController : Controller
{
private MovieContext context { get; set; }
public MovieController(MovieContext ctx)
{
context = ctx;
}
[HttpGet]
public IActionResult Add()
{
ViewBag.Action = "Add";
ViewBag.Genres = context.Genres.OrderBy(g => g.Name).ToList();
return View("Edit", new Movie());
}
[HttpGet]
public IActionResult Edit(int id)
{
ViewBag.Action = "Edit";
ViewBag.Genres = context.Genres.OrderBy(g => g.Name).ToList();
var movie = context.Movies.Find(id);
return View(movie);
}
[HttpPost]
public IActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
if (movie.MovieId == 0)
context.Movies.Add(movie);
else
context.Movies.Update(movie);
context.SaveChanges();
return RedirectToAction("Index", "Home");
}
else
{
ViewBag.Action = (movie.MovieId == 0) ? "Add": "Edit";
ViewBag.Genres = context.Genres.OrderBy(g => g.Name).ToList();
return View(movie);
}
}
[HttpGet]
public IActionResult Delete(int id)
{
var movie = context.Movies.Find(id);
return View(movie);
}
[HttpPost]
public IActionResult Delete(Movie movie)
{
context.Movies.Remove(movie);
context.SaveChanges();
return RedirectToAction("Index", "Home");
}
}
}
This is my model - most developers say the model manages the data. When working with EF Core, most developers start coding the model class first. This model defines 4 public properties (Name, Year, Rating and Genre) and assigns data validation attributes.
using System;
using System.ComponentModel.DataAnnotations;
namespace MovieList.Models
{
public class Movie
{
// EF will instruct the database to automatically generate this value
public int MovieId { get; set; }
[Required(ErrorMessage = "Please enter a name.")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter a year.")]
[Range(1889, 2050, ErrorMessage = "Year must be between 1889 and now.")]
public int? Year { get; set; }
[Required(ErrorMessage = "Please enter a rating.")]
[Range(1, 5, ErrorMessage = "Rating must be between 1 and 5.")]
public int? Rating { get; set; }
[Required(ErrorMessage = "Please enter a genre.")]
public string GenreId { get; set; }
public Genre Genre { get; set; }
public string Slug =>
Name?.Replace(' ', '-').ToLower() + '-' + Year?.ToString();
}
}
This is my View - Home/Index. A view is basically an HTML template with embedded Razor markup. This view is a strongly typed view of a collection coming from the Home controller. I'm also using a foreach statement to loop through the collection of objects.
@model List<Movie>
@{
ViewBag.Title = "My Movies";
}
<h2>Movie List</h2>
<a asp-controller="Movie" asp-action="Add">Add New Movie</a>
<table class="table table-bordered table-striped">
<thead>
<tr><th>Name</th>
<th>Year</th>
<th>Genre</th>
<th>Rating</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var movie in Model) {
<tr>
<td>@movie.Name</td>
<td>@movie.Year</td>
<td>@movie.Genre.Name</td>
<td>@movie.Rating</td>
<td>
<a asp-controller="Movie" asp-action="Edit"
asp-route-id="@movie.MovieId"
asp-route-slug="@movie.Slug">Edit</a>
<a asp-controller="Movie" asp-action="Delete"
asp-route-id="@movie.MovieId"
asp-route-slug="@movie.Slug">Delete</a>
</td>
</tr>
}
</tbody>
</table>