There are two separate model classes that need to be created: a model that represents a to-do item stored in the database (sometimes called an entity), and the model that will be combined with a view (the MV in MVC) and sent back to the user's browser. Because both of them can be referred to as "models", I'll refer to the latter as a view model.
First, create a class called TodoItem
in the Models directory:
Models/TodoItem.cs
using System;
using System.ComponentModel.DataAnnotations;
namespace AspNetCoreTodo.Models
{
public class TodoItem
{
public Guid Id { get; set; }
public bool IsDone { get; set; }
[Required]
public string Title { get; set; }
public DateTimeOffset? DueAt { get; set; }
}
}
This class defines what the database will need to store for each to-do item: an ID, a title or name, whether the item is complete, and what the due date is. Each line defines a property of the class:
-
The Id property is a guid, or a globally unique identifier. Guids (or GUIDs) are long strings of letters and numbers, like
43ec09f2-7f70-4f4b-9559-65011d5781bb
. Because guids are random and are extremely unlikely to be accidentally duplicated, they are commonly used as unique IDs. You could also use a number (integer) as a database entity ID, but you'd need to configure your database to always increment the number when new rows are added to the database. Guids are generated randomly, so you don't have to worry about auto-incrementing. -
The IsDone property is a boolean (true/false value). By default, it will be
false
for all new items. Later you'll use write code to switch this property totrue
when the user clicks an item's checkbox in the view. -
The Title property is a string (text value). This will hold the name or description of the to-do item. The
[Required]
attribute tells ASP.NET Core that this string can't be null or empty. -
The DueAt property is a
DateTimeOffset
, which is a C# type that stores a date/time stamp along with a timezone offset from UTC. Storing the date, time, and timezone offset together makes it easy to render dates accurately on systems in different timezones.
Notice the ?
question mark after the DateTimeOffset
type? That marks the DueAt property as nullable, or optional. If the ?
wasn't included, every to-do item would need to have a due date. The Id
and IsDone
properties aren't marked as nullable, so they are required and will always have a value (or a default value).
Strings in C# are always nullable, so there's no need to mark the Title property as nullable. C# strings can be null, empty, or contain text.
Each property is followed by get; set;
, which is a shorthand way of saying the property is read/write (or, more technically, it has a getter and setter methods).
At this point, it doesn't matter what the underlying database technology is. It could be SQL Server, MySQL, MongoDB, Redis, or something more exotic. This model defines what the database row or entry will look like in C# so you don't have to worry about the low-level database stuff in your code. This simple style of model is sometimes called a "plain old C# object" or POCO.
Often, the model (entity) you store in the database is similar but not exactly the same as the model you want to use in MVC (the view model). In this case, the TodoItem
model represents a single item in the database, but the view might need to display two, ten, or a hundred to-do items (depending on how badly the user is procrastinating).
Because of this, the view model should be a separate class that holds an array of TodoItem
s:
Models/TodoViewModel.cs
namespace AspNetCoreTodo.Models
{
public class TodoViewModel
{
public TodoItem[] Items { get; set; }
}
}
Now that you have some models, it's time to create a view that will take a TodoViewModel
and render the right HTML to show the user their to-do list.