Now that we've had some practice building ASP.NET MVC Core applications, let's create an MVC interface for the to do list program we made last section. We'll then continue building upon this codebase throughout the course.
We'll continue from where we left off in the last section. Your repository should match the code from the first commit of the following example repository except for two things:
.gitignore
file, which we'll create shortly. Priority
property from last section's lesson on overloaded constructors, which we've removed. Example GitHub Repo for To Do List after Section Two Lessons
We'll update this project to work with ASP.NET Core MVC. First we'll add the necessary components to our project structure.
ToDoList
production project, create the following files:
Program.cs
Startup.cs
ToDoList
, create the following subdirectories:
Controllers
Views
ToDoList/Controllers
create a HomeController.cs
file.ToDoList/Views
create a Home
subdirectory.
Index.cshtml
file.ToDoList.Solution
, create a .gitignore
file.The resulting structure should look like this:
ToDoList.Solution ├── .gitignore ├── ToDoList │ ├── Controllers │ │ └── HomeController.cs │ ├── Models │ │ └── Item.cs │ ├── Program.cs │ ├── Startup.cs │ ├── ToDoList.csproj │ └── Views │ └── Home │ └── Index.cshtml └── ToDoList.Tests ├── ModelTests │ └── ItemTests.cs └── ToDoList.Tests.csproj
We'll also add the MVC framework package by updating the production project's .csproj
file to include .Web
in the SDK:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
Navigate to the ToDoList
production project in the terminal and run $ dotnet restore
.
Startup
ClassWe'll populate ToDoList/Startup.cs
with the same general configuration code we've used so far:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace ToDoList
{
public class Startup
{
public Startup(IWebHostEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseEndpoints(routes =>
{
routes.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
}
}
Program
ClassWe'll also populate ToDoList/Program.cs
with configuration code as well:
using System.IO;
using Microsoft.AspNetCore.Hosting;
namespace ToDoList
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}
Item
ModelThe Item
model should look like this from the last course section:
using System.Collections.Generic;
namespace ToDoList.Models
{
public class Item
{
public string Description { get; set; }
private static List<Item> _instances = new List<Item> {};
public Item (string description)
{
Description = description;
_instances.Add(this);
}
public static List<Item> GetAll()
{
return _instances;
}
public static void ClearAll()
{
_instances.Clear();
}
}
}
.gitignore
We'll add the following to our .gitignore
file to keep our directory tidy:
*/obj/
*/bin/
Let's also ensure any obj
or bin
directories already committed are no longer tracked by Git with the following commands in the top level of our project:
$ git rm --cached obj -r
$ git rm --cached bin -r
(If you receive a did not match any files
response, it means you're already ignoring these directories so there was nothing to remove from Git. This is normal.)
In the ToDoList/Controllers/HomeController.cs
we'll add the standard import statements, namespace, and class:
using Microsoft.AspNetCore.Mvc;
using ToDoList.Models;
namespace ToDoList.Controllers
{
public class HomeController : Controller
{
}
}
In addition to the Microsoft.AspNetCore.Mvc
namespace, we're also using
our ToDoList.Models
namespace. This grants access to our Item
class in the controller.
Now we can add our first route:
using Microsoft.AspNetCore.Mvc;
using ToDoList.Models;
namespace ToDoList.Controllers
{
public class HomeController : Controller
{
[Route("/")]
public ActionResult Index()
{
Item starterItem = new Item("Add first item to To Do List");
return View(starterItem);
}
}
}
We create an Index()
route method with a route decorator specifying a URL path of /
, which means this is the root route for localhost:5000
.
When the route is invoked, we create a placeholder Item
to populate our to do list. We can access Item
s because we are using ToDoList.Models;
at the top of this file.
We pass starterItem
into the View()
method. Let's create a corresponding view now.
Add the following to Index.cshtml
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My To-Do List!</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<h1>To Do List</h1>
<ul>
<li>@Model.Description</li>
</ul>
</body>
</html>
We use @Model.Description
to display the property of the starterItem
object we passed into View()
in the controller.
Let's check out the project in the browser. Run the following in the ToDoList
production project directory to install packages:
$ dotnet restore
$ dotnet build
Our build report should have no warnings or errors.
Now let's run our project:
$ dotnet watch run
If we visit http://localhost:5000
, our to do list homepage loads correctly.
Lesson 21 of 38
Last updated more than 3 months ago.